Select limited rows from multiple tables - sql

So this is fairly common knowledge to select rows from multiple tables and stack the results on top of each other:
SELECT * FROM table1
UNION
SELECT * FROM table2
UNION
...
However, if I want only a limited number of rows from each table, then how should I write it?
SELECT * FROM table1 LIMIT 2
UNION
SELECT * FROM table2 LIMIT 2
UNION
...
Clearly doesn't work.
Note that in my case, I have 51 tables, all with the same exact columns.

could be work this way
( SELECT * FROM table1 LIMIT 2 )
UNION
( SELECT * FROM table2 LIMIT 2 )
UNION
...

Related

Union All have mismatched column count

I am trying to union some table. But I am having some issues with the query as I have the following error:
Queries in UNION ALL have mismatched column count; query 1 has 10 columns, query 2 has 12 columns at [3:1]
The query used is:
SELECT * FROM `table_1`
UNION ALL
SELECT * ,null, FROM `table_2`
UNION ALL
SELECT * FROM `table_3`
UNION ALL
SELECT * FROM `table_4`
UNION ALL
SELECT * , null, FROM `table_5`
Please someone have any suggestions?
In a UNION ALL all queries need to be the same number of columns.
You need to post the schema of all tables. But according to the error message you posted, this could help for the 2 first tables:
SELECT *, null FROM `table_1` -- assuming table_1 has 10 columns, add 1 more empty to match the table_2
UNION ALL
SELECT * FROM `table_2` -- assuming table_2 has 11 columns
-- make the same to the rest of queries
-- UNION ALL
-- SELECT * FROM `table_3`
-- UNION ALL
-- SELECT * FROM `table_4`
-- UNION ALL
-- SELECT * , null, FROM `table_5`
Update:
Adding a example of union all declaring the columns:
SELECT
col1_str,
col2_str,
col3_int,
col4_int
FROM `table_1`
UNION ALL
SELECT
col2_str,
FORMAT_DATE("%Y-%m-%d", col1_date) as col1_str, -- transform a date column to string
col3_int,
null
FROM `table_2`

How to Union Multiple Tables with same column names on Google Big Query?

I am trying to create a union with 3 tables that have the same column names. However, the queries tested seems not to be working.
The first query that I have used is the following:
Select * FROM table1
UNION ALL
SELECT * FROM table2
SELECT * FROM table3
UNION ALL
The second query used is the following:
SELECT *
FROM
(select * from table_1),
(select * from table_2),
(select * from table_3)
Both of them are not working for me. Please someone can help me with this?
This should work if columns are identical:
SELECT * FROM table1 UNION ALL
SELECT * FROM table2 UNION ALL
SELECT * FROM table3

SQL statement to return non-intersection records

I was recently asked this question and was a little stumped so I want to ask the experts...
Given two tables A & B, I want to return all the values from A and B that do not overlap. Think of two overlapping circles; how do we return all the data that is NOT in the overlapping center section? And, I had to use ANSI Standard SQL rather than Oracle syntax.
Assuming we want everything exclusive to both A & B, my answer was
select *
from A
cross join B
minus
(select a.common_column from a
intersect
select b.common_column)
Does this look correct, or even close? If it is correct, is there a more efficient way to do this?
BTW - my solution was soundly rejected....
Thank you!
Given the tables A and B, you are looking for (A U B) - (A & B). In other words, you need A union B minus their intersection. Remember A and B must be union-compatible for this query to work. I would do:
(select * from A
union
select * from B
)
minus
(select * from A
intersect
select * from B
)
May be full outer join?
select coalesce(A.col, B.col)
from A full outer join B on A.col = B.col
where A.col is null or B.col is null;
For computing a set symmetric difference, you can use a combination of MINUS and UNION ALL:
select * from (
(select * from A
minus
select * from B)
union all
(select * from B
minus
select * from A)
)
Your query was rejected because it is syntactically incorrect: the number of columns differ and it confuses cross join and union all. However, I think you have the right idea for solving this.
You can easily fix this:
(select *
from A
union all
select *
from B
) minus
(select *
from A
intersect
select *
from B
);
That is, combine everything using union all and then subtract the rows that occur in both tables.
Of course, if there is a single id, then you can use the id with join and other operations.
Just like Frank Schmitt answered in the meantime:
Here it is including a data example:
WITH
table_a(name) AS (
SELECT 'From_A_1'
UNION ALL SELECT 'From_A_2'
UNION ALL SELECT 'From_A_3'
UNION ALL SELECT 'From_A_4'
UNION ALL SELECT 'From_A_5'
UNION ALL SELECT 'From_BOTH_6'
UNION ALL SELECT 'From_BOTH_7'
UNION ALL SELECT 'From_BOTH_8'
)
,
table_b(name) AS (
SELECT 'From_B_1'
UNION ALL SELECT 'From_B_2'
UNION ALL SELECT 'From_B_3'
UNION ALL SELECT 'From_B_4'
UNION ALL SELECT 'From_B_5'
UNION ALL SELECT 'From_BOTH_6'
UNION ALL SELECT 'From_BOTH_7'
UNION ALL SELECT 'From_BOTH_8'
)
(SELECT * FROM table_a EXCEPT SELECT * FROM table_b)
UNION ALL
(SELECT * FROM table_b EXCEPT SELECT * FROM table_a)
ORDER BY name
;
name
From_A_1
From_A_2
From_A_3
From_A_4
From_A_5
From_B_1
From_B_2
From_B_3
From_B_4
From_B_5
You will need to select all the data from both tables, except where they overlap, and then combine the data with a union. The code provided should work for your example.
SELECT *
FROM
(
SELECT * FROM Table1
EXCEPT SELECT * FROM Table2
)
UNION
SELECT *
FROM
(
SELECT * FROM Table2
EXCEPT SELECT * FROM Table1
)
Hope this helps.

SELECT TOP ... FROM UNION

What is the best way to SELECT TOP N records from UNION of 2 queries?
I can't do
SELECT TOP N ... FROM
(SELECT ... FROM Table1
UNION
SELECT ... FROM Table2)
because both queries return huge results I need every bit of optimization possible and would like to avoid returning everything. For the same reason I cannot insert results into #TEMP table first either.
I can't use SET ROWCOUNT N either because I may need to group results and this command will limit number of grouped rows, and not underlying row selections.
Any other ideas? Thanks!
Use the Top keyword for inner queries also:
SELECT TOP N ... FROM
(SELECT TOP N... FROM Table1
UNION
SELECT TOP N... FROM Table2) as result
You could try the following. It uses a CTE which would give you the results of both queries first and then you would select your TOP N from the CTE.
WITH table_cte (
(
[col1],
[col2],
...
)
AS
(
SELECT *
FROM table1
UNION ALL
SELECT *
FROM table2
)
SELECT TOP 1000 * FROM table_cte

UNION ALL query: "Too Many Fields Defined"

I'm trying to get a UNION of 3 tables, each of which have 97 fields. I've tried the following:
select * from table1
union all
select * from table2
union all
select * from table3
This gives me an error message:
Too many fields defined.
I also tried explicitly selecting all the field names from the first table (ellipses added for brevity):
select [field1],[field2]...[field97] from table1
union all
select * from table2
union all
select * from table3
It works fine when I only UNION two tables like this:
select * from table1
union all
select * from table2
I shouldn't end up with more than 97 fields as a result of this query; the two-table UNION only has 97. So why am I getting Too many fields with 3 tables?
EDIT: As RichardTheKiwi notes below, Access is summing up the field count of each SELECT query in the UNION chain, which means that my 3 tables exceed the 255 field maximum. So instead, I need to write the query like this:
select * from table1
union all
select * from
(select * from table2
union all
select * from table3)
which works fine.
It appears that the number of fields being tracked (limit 255) is counted against ALL parts of the UNION ALL. So 3 x 97 = 291, which is in excess. You could probably create a query as a UNION all of 2 parts, then another query with that and the 3rd part.
I had two tables with 173 fields each (2 x 173 > 255!). So I had to resort to splitting the tables in half (keeping the primary key in both), before using the UNION statement and reassembling the resulting output tables using a JOIN.
select u1.*, u2.*
from (
select [field1_PKID],[field2],...,[field110]
from table1
union all
select [field1_PKID],[field2],...,[field110]
from table2
) as u1
inner join (
select [field1_PKID],[field111],...,[field173]
from table1
union all
select [field1_PKID],[field111],...,[field173]
from table2
) as u2
on [u1].[field1_PKID] = [u2].[field2_PKID]
Perhaps if your 3 tables have duplicate records you can go with UNION instead of UNION ALL which may reduce the number of fields to be tracked. Because UNION will always serve the business purpose which removes duplicates. In that case your query will be like following,
select * from table1
union
select * from table2
union
select * from table3;