Data Virtualization & Federated Queries

One SQL statement across all your databases.

Your orders are in MySQL. Your customers are in PostgreSQL. The targets everyone argues about live in a SQL Server box at head office. A federated query lets you write one ordinary SELECT that reads all three at once and hands you a single table — no exports, nothing copied anywhere, and nothing new to open on your firewall.

On every plan, including Free · Free runs 2 sources and 250 result rows — the ceilings grow with your tier

One SQL box, not a join builder Databases in different offices, clouds and countries No inbound firewall rule, ever Refuses rather than guess

38 database connectors — join across any of them, in any combination

Microsoft SQL ServerPostgreSQLMySQLMariaDBOracleSnowflakeGoogle BigQuerySQLiteMicrosoft AccessDuckDBSupabase

Alongside them in Query Streams: 8 API connectors, queried with the same SQL

StripeHubSpotShopifyGoogle AdsGoogle Analytics 4Google Search ConsoleShipStationiTick

53 sources in total. Your API connectors are queried with SQL like everything else — and a federated statement joins your database connections. See the API Connector

Data virtualization, in one statement

Put the connection name in front of the table

That is the only new idea on this page. Each highlighted name below is a different database, in a different place, reached by a different Network Agent — and it is still one query.

revenue-by-region.sql 3 connections · 3 agents · 1 statement
-- one federated query · nothing copied anywhere
SELECT   c.region,
         COUNT(*)      AS orders,
         SUM(o.total)  AS revenue,
         t.target
FROM     mysql_prod.shop.orders1 o
JOIN     pg_crm.public.customers2 c ON c.id = o.customer_id
JOIN     mssql_erp.dbo.region_targets3 t ON t.region = c.region
WHERE    o.placed_at >= DATE '2026-07-01'
GROUP BY c.region, t.target
ORDER BY revenue DESC;
Each database handles: its own filtering and grouping We handle: the joins across them and the ordering

mysql_prod, pg_crm and mssql_erp are simply the names you gave your own connections — the three parts are connection, schema, table. This is what people mean by a federated database: three separate databases answering one question, with nothing merged and nothing moved. Illustrative schema; your tables will be your tables.

Where each name resolves

1 MySQL mysql_prod MySQL · shop.orders Cloud agent Filters to July itself, then totals revenue per customer before sending anything.
2 PostgreSQL pg_crm PostgreSQL · public.customers Regional agent Returns just the id and region columns — the only two the query names.
3 Microsoft SQL Server mssql_erp SQL Server · dbo.region_targets Head office agent Hands over the target per region, written as T-SQL so it runs natively.

Three agents, three networks, one statement — and none of them opened a port to do it.

What does not change

More reach, not more exposure

Reading two databases at once uses exactly the same path as reading one. Nothing new is opened up to get it.

Outbound only

The agent opens one encrypted connection out to Query Streams and carries both the request and the results over it. No inbound port, no VPN, no firewall change — and your credentials never leave your network.

Read-only, every piece

Each piece of the query is checked before it goes anywhere: SELECT, WITH and EXPLAIN only. A federated query cannot write to any of your databases, and anything rejected never reaches them at all.

It cannot run away with your server

There is a ceiling on how much any one database may hand over for a single query, and the agent stops the moment it is reached. A mistake in a WHERE clause costs you an error message, not an afternoon.

How it works

Three steps, and none of them is a data pipeline

01

Pick your connections

Choose two or more of the connections your team already set up. Two is the minimum — that is what makes a query federated. Nothing gets copied and no new passwords are created.

02

Write one statement

Name each table as connection.schema.table, then write normal SQL. Before you run it you can read the plan: which database is being asked what. Or describe the question and let Nova draft it.

03

Save it like any other query

Once it works, it is a saved query — so it can be shared, given filters, sent as a weekly report, published as an API endpoint or pulled into a spreadsheet.

Why it is fast

Each database does its own share of the work

The lazy way to join two databases is to drag both tables across the network and sort it out afterwards. That is slow, and it means far more of your data leaves your building than the question needed.

So we do the opposite. Filtering, picking columns and counting up totals are handed back to each database to do itself, in its own language. A report that groups millions of rows sends back the handful of grouped totals — not the millions of rows behind them.

Whatever is left over, we do — and we show you which is which. Joining across databases is our job, because no single one of them can see the others. The plan spells out what each database was asked for and what we finished off, so an expensive query is obvious before you run it.

THE SLOW WAY the whole table travels filter it here THE QUERY STREAMS WAY filter + total in the database 12 rows stitch one answer
The honest answer

It would rather refuse than quietly be wrong

Here is the awkward truth about joining separate databases: they do not always agree with each other. Two of them can be handed the same question and come back with answers that differ in the last decimal place, or in what counts as equal, or in what “first ten” means.

If you are new to this, the short version: a database is not just a bucket of rows. It has its own opinions about how to add up money, how to sort words, and where empty values belong. Ask two different databases to sort the same list of customer names and you can genuinely get two different orders — not because one is broken, but because they were built with different rules. Any tool that joins databases has to deal with that. Most quietly pick one answer and hope. We do not.

What we do instead has exactly two outcomes, and the Query Builder shows you which one you got: a plan pill that reads ready or refused as you type, and a Plan tab with the full working.

Usually: we just do it ourselves

When the disagreement is about how a calculation is done, we stop asking your database to do that part and do it in the stitch step, where there is one consistent set of rules. It costs a little speed. It costs you no accuracy and no attention — you are not asked to do anything.

  • Money and precision. Databases widen and round decimals differently once totals get large. If adding up in-source could round differently from adding up centrally, we bring the numbers back and add them up ourselves.
  • Sorting text. Whether a comes before B, and how accents compare, is a per-database setting. Comparisons that depend on it are settled centrally, not pushed down.
  • Ranking and running totals. Window functions — row numbers, running totals, “top 3 per region” — are always computed after the pieces arrive, because no single source can see the others.
Sometimes: we stop and tell you

When carrying on would change which rows come back — not just how fast — there is no safe way to guess. So the query does not run, and the message names the exact expression and the exact database, in your own SQL, so you know what to edit.

  • A function that source cannot do. If your filter uses something we cannot faithfully express in that database’s dialect, the only alternatives are to send it a wider query than you wrote or to invent an equivalent. Both are wrong answers, so we refuse.
  • Row limits inside a piece. A LIMIT or TOP applied to one source before the join returns an arbitrary handful of rows, then joins those — a plausible-looking table of nonsense. Limits belong to the finished result.
  • A moved goalpost. If a connection was re-pointed at a different database since the query was planned, the stored plan is stale and we ask for a re-plan rather than run yesterday’s plan against today’s data.

Three refusals, and what each one is telling you

Refused

Cannot push LOWER(c.email_domain) = ? down to mssql_erp: function not in the pushdown allowlist.

In other words: your filter wraps a column in a function that source cannot be trusted to apply the same way we would, so we cannot guarantee it returns the same rows. What to do: compare the plain column instead, or move that condition outside the source — the message tells you which source to look at.

Refused

LIMIT 100 cannot be applied to a single source before the join: the result would be 100 arbitrary rows, not the first 100 of your answer.

In other words: “first 100” only means something once everything has been joined and sorted. What to do: leave the limit on the statement as a whole, which is where it does what you expect.

Needs a re-plan

Source 2 now points at a different connection or database than when this query was planned.

In other words: somebody changed what pg_crm refers to. What to do: open it in the Query Builder and re-plan — one click, and you can see the new plan before running it.

The rule underneath all of it: if a query would come back wrong, we refuse. If it would merely come back slowly, we run it and warn you. Wrong data is never a trade-off we make on your behalf.

You are not left to fix a refusal alone, either. Nova sits beside the editor in the Query Builder and speaks this whole system fluently: ask, and it explains the refusal in plain words, rewrites the statement so it runs, and checks the new plan for you. And if you would rather skip writing the SQL at all, describe the question and Nova drafts the federated statement itself.

And for anyone who wants the detail rather than the reassurance: the Query Builder’s Plan tab lists every source, the query it was actually sent, which of your conditions it applied itself, and which parts we finished off centrally. Nothing about the decision is hidden — including the parts where we chose the slower, safer route.

Nothing is a special case

A federated query is just a query

It is not a separate product with its own rules. Once it is saved, every other part of Query Streams treats it like anything else you have written.

Query Builder

Write it in the same editor, with the same schema tree beside you. A Plan tab shows what each database was asked for; an Insights tab charts how each one performed.

Nova AI

Nova AI

Describe the question in English and Nova reads your schemas and drafts the statement — including which connection each table belongs to. It can run it and chart the result too.

Google Sheets

Google Sheets

Pick the saved query in the add-on and the combined results land in your cells, formatted and refreshable — the same as any single-database query.

Microsoft Excel

Excel

Same story in Excel: run one or run a whole sheet of them, with frozen headers, filters and in-place updates that leave your own formula columns alone.

REST API

Database REST API

Publish the cross-database result as a JSON endpoint with a key, and whoever consumes it never needs to know it came from three systems.

MCP

MCP for AI assistants

Claude and other assistants can list and run your federated queries through MCP, so “how did each region do last week” is answerable in chat.

Reports & alerts

Put it on a schedule and the combined figures arrive in Slack, Google Chat, Discord, Telegram or email — or set a threshold and only hear about it when something moves.

Automation & sharing

Sync the result into a spreadsheet on a schedule, or share the query with a colleague who only sees filters and a Run button — never your SQL or your connections.

Where it earns its keep

The reports that used to be two exports and a VLOOKUP

Almost nobody has one database. There is the ERP, the shop, the CRM, and whatever the last acquisition ran on.

Orders here, customers there

The shop writes orders into MySQL; the CRM keeps customers and regions in PostgreSQL. “Revenue by region” stops being two exports and a lookup, and becomes one saved query anyone can re-run.

After an acquisition

Two companies, two stacks, one board pack due Friday. You get the combined view on day one, while the real migration takes the eighteen months it always takes.

Stock against sell-through

Stock levels live in the warehouse system in another country; sales live in the shop database. One statement puts them side by side — and the same statement can then arrive every Monday as a report.

One database per site, one number

The same schema deployed per country, per tenant or per shop floor. Add them up in one statement instead of maintaining a script that runs the query five times and totals it by hand.

Plain definitions

Federated database, data federation, data virtualization

Three names for overlapping ideas, and plenty of marketing has blurred them. Here is what each one means, and which bit we actually do.

01

A federated database

A federated database (or federated database system) makes several separate databases behave like one, without merging them. Each keeps its own storage, its own engine and its own owner; a layer above them takes your query and works out who answers which part.

That layer is what Query Streams is. There is no new database underneath, and nothing is copied into one.

02

Data federation

Data federation is the approach itself: leave data where it was written and query across it when you need it, instead of extracting everything into a central copy first. The alternative is a pipeline plus a warehouse — move it all overnight, then only ever query the copy.

Both are legitimate. Federation wins when the question spans systems, when the data has to stay put, or when a warehouse project would cost more than the answer is worth. A warehouse still wins for heavy historical analysis over enormous volumes.

03

Data virtualization

Data virtualization is the bigger enterprise category built on federation — usually federated querying plus a modelling layer, caching and governance tooling, sold as a platform of its own.

We are deliberately the narrow, honest slice of that: federated querying over the connections you already have, inside the tool your team already writes queries in. No modelling project, no server of your own to run, no consultants.

Federated query FAQ

What is a federated query?

A federated query is one SQL statement that reads from more than one separate database and gives you a single combined result. Nothing is copied first: your statement is split into a small query per database, each one answers the part it can, and the pieces are joined into the answer. In Query Streams a statement becomes federated as soon as it names two or more of your connections.

Do my databases need to be in the same place?

No. They can be in different offices, different cloud accounts, different countries, or a mix of all three — one in a server room, one in a private cloud network, one on a machine in a warehouse. Each location runs a Network Agent, and each agent reaches Query Streams by dialling out. As far as your firewall is concerned that is just an ordinary outbound connection, so there is nothing to open and no VPN to build.

You can also point several databases on one server at the same agent; one agent per location is normal, not one per database.

Do I need a data warehouse or an ETL pipeline as well?

Not for this. There is nothing to load and no schedule to babysit — the query reads your live databases at the moment you run it, so the answer cannot be stale the way last night’s copy can. What federation does not replace is heavy historical analysis over very large volumes; that is still a warehouse’s job. Rough test: if the question spans systems and needs to be current, federate it.

Which databases can I join together?

Any of your database connections, in any mix: SQL Server, PostgreSQL, MySQL, MariaDB, Oracle, Snowflake, BigQuery, SQLite, Access and DuckDB. Each database is asked in its own dialect, so the same statement can send TOP to SQL Server and LIMIT to PostgreSQL without you thinking about it.

Databases genuinely differ in what they can compute and how they sort and round, so not every combination of every expression can be answered exactly. When that happens you get a specific message naming the expression, rather than a number that is nearly right.

Is it slower than querying one database?

It depends on how much of the work each database can do for itself — which is exactly what we optimise for, and exactly what the plan shows you. When the filtering and grouping all happen inside your databases, very little data moves and it feels like a normal query. When a big join has to be finished off by us, more moves, and the plan says so before you run it. Each database also has a ceiling per query, so a mistake stops early instead of grinding.

Is it safe to point one query at several production databases?

It uses the same security model as every other query you run here. Each piece travels through your own Network Agent over one encrypted outbound connection — no inbound port, no VPN, no firewall change — and your database credentials never leave your network. Every piece is checked read-only (SELECT, WITH, EXPLAIN), a federated query cannot write anywhere, and each database only ever sees a query touching the columns you named.

How is this different from Trino, Presto or Denodo?

The idea is the same one Trino and Presto made popular: one SQL statement, pushed down to many sources. The difference is what you have to run and learn. Those are clusters you deploy, tune and wire into your network; the data-virtualization platforms add a modelling layer and a licence to match. Ours is the same capability delivered inside the tool your team already queries with, reaching the connections you already set up, with no server of your own to operate.

The other difference is that we refuse. Where databases disagree in a way that could change a figure, we stop and name the expression we could not handle instead of returning something plausible.

What can I do with the result?

Everything you can do with any saved query, because that is what it is. Save it, share it with your team, give it filters, schedule it as a report into Slack or email, publish it as a REST endpoint, or pull the results into Excel and Google Sheets. Nova can also read your schemas and draft the statement if you would rather describe the question than write the joins.

Your databases stay where they are. The question stops caring.

Name two connections, write one statement, read the plan before you run it. No pipeline, no warehouse, no firewall ticket.

Federated queries are on every plan, including Free