27

BigQuery does not seem to have support for UNION yet: https://developers.google.com/bigquery/docs/query-reference

(I don't mean unioning tables together for the source. It has that.)

Is it coming soon?

Pedram
  • 6,256
  • 10
  • 65
  • 87
mdahlman
  • 9,204
  • 4
  • 44
  • 72

6 Answers6

61

If you want UNION so that you can combine query results, you can use subselects in BigQuery:

SELECT foo, bar 
FROM
  (SELECT integer(id) AS foo, string(title) AS bar 
   FROM publicdata:samples.wikipedia limit 10),
  (SELECT integer(year) AS foo, string(state) AS bar 
   FROM publicdata:samples.natality limit 10);

This is almost exactly equivalent to the SQL

SELECT id AS foo, title AS bar 
FROM publicdata:samples.wikipedia limit 10
UNION ALL
SELECT year AS foo, state AS bar 
FROM publicdata:samples.natality limit 10;

(note that if want SQL UNION and not UNION ALL this won't work)

Alternately, you could run two queries and append the result.

Jordan Tigani
  • 26,089
  • 4
  • 60
  • 63
  • ahh... very clever. Appending two queries isn't an option in my case, but this construction looks like it should work. – mdahlman May 18 '12 at 04:16
  • 2
    Just as a note, as you mentioned, this is not exactly a UNION, but rather a UNION ALL [See other post](http://stackoverflow.com/questions/49925/what-is-the-difference-between-union-and-union-all) – hoggkm Oct 27 '14 at 16:22
  • hello @Jordan-Tigani if i call the above like query then top records will be of wikipedia and then of natality. I want to know sequence do maintain or not. just want to clerify. – murtaza.webdev Mar 16 '15 at 05:58
  • BigQuery makes no sequencing guarantees unless you use an ORDER BY. So if you use a table union you have no guarantee in which order you'll get results. – Jordan Tigani Mar 19 '15 at 23:20
  • FYI: in sub queries IGNORE CASE at end of all queries not in sub queries. i.e. SELECT bar FROM (SELECT string(title) AS bar FROM publicdata:samples.wikipedia where title contains 'any' limit 10), (SELECT string(state) AS bar FROM publicdata:samples.natality where state contains 'any' limit 10) IGNORE CASE; (GOT ISSUE SO JUST SHARED) – murtaza.webdev May 05 '15 at 06:26
  • Guys I am trying to append to a table.. Is that equivalent to UNION answer as mentioned above or will it be an equivalent to UNION ALL that we do in regular SQL..? – Teja Jun 05 '15 at 21:25
  • This is equivalent to UNION ALL. – Jordan Tigani Jun 05 '15 at 21:59
  • Running this in GCP BigQuery console, I'm getting "Column name is ambiguous". If I replace the column names with *, the result concatenates the _columns_, not the _rows_. Has BigQuery changed the spec? – Sarah Messer Feb 25 '21 at 22:06
5

BigQuery recently added support for Standard SQL, including the UNION operation.


When submitting a query through the web UI, just make sure to uncheck "Use Legacy SQL" under the SQL Version rubric: enter image description here

assaflavi
  • 417
  • 4
  • 9
  • 2
    What is important though is that you should use UNION with a second keyword:UNION ALL or UNION DISTINCT, see [the following link](https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#union) – Rogier Werschkull Jan 11 '17 at 07:59
  • @RogierWerschkull true dat. – assaflavi Mar 29 '17 at 08:17
3

You can always do:

SELECT * FROM (query 1), (query 2);

It does the same thing as :

SELECT * from query1 UNION select * from query 2;
Kristian
  • 21,204
  • 19
  • 101
  • 176
vgt
  • 217
  • 1
  • 4
2

Note that, if you're using standard SQL, the comma operator now means JOIN - you have to use the UNION syntax if you want a union:

In legacy SQL, the comma operator , has the non-standard meaning of UNION ALL when applied to tables. In standard SQL, the comma operator has the standard meaning of JOIN.

For example:

#standardSQL
SELECT
    column_name,
    count(*)
from
    (SELECT * FROM me.table1 UNION ALL SELECT * FROM me.table2)
group by 1
Joshua Conner
  • 882
  • 8
  • 21
1

This helped me out very much for doing a UNION INTERSECT with big query's StandardSQL.

#standardSQL
WITH
  a AS (
  SELECT
    *
  FROM
    table_a),
  b AS (
  SELECT
    *
  FROM
    table_b)
SELECT
  *
FROM
  a INTERSECT DISTINCT
SELECT
  *
FROM
  b

I STOLE/MODIFIED THIS EXAMPLE FROM: https://gist.github.com/yancya/bf38d1b60edf972140492e3efd0955d0

Weezy.F
  • 454
  • 5
  • 10
0

Unions are indeed supported. An excerpt from the link that you posted:

Note: Unlike many other SQL-based systems, BigQuery uses the comma syntax to indicate table unions, not joins. This means you can run a query over several tables with compatible schemas as follows:

// Find suspicious activity over several days

SELECT FORMAT_UTC_USEC(event.timestamp_in_usec) AS time, request_url
  FROM [applogs.events_20120501], [applogs.events_20120502], [applogs.events_20120503]
  WHERE event.username = 'root' AND NOT event.source_ip.is_internal;
Kristian
  • 21,204
  • 19
  • 101
  • 176
Emre Colak
  • 814
  • 1
  • 9
  • 15
  • 1
    That refers to unioning tables together for the source. That's the feature I specifically mentioned as not being what I need. – mdahlman Apr 08 '13 at 22:35
  • Ah I see. I didn't get what you mean by "unioning together for the source" initially. I actually end up doing something similar to what Jordan suggested for a scenario where I need the table names in the result set. I put the table_name in the inner queries and select them from the outer query e.g. SELECT table_name, title, state FROM (SELECT "publicdata:samples.wikipedia" AS table_name, string(title) AS title FROM publicdata:samples.wikipedia limit 10), (SELECT "publicdata:samples.natality" AS table_name, string(state) AS state FROM publicdata:samples.natality limit 10) – Emre Colak Apr 09 '13 at 18:24