PostgreSQL - UNION of tables based on number of columns - sql

I'm working in PostgreSQL, and I want to UNION all tables with 11 columns, of a database called 'postgres'.
The list of the mentioned tables, I get it with the following query.
with
completo_tablas as (
select column_name, table_name from information_schema.columns
where table_schema='public'
)
--,tablas as (
select table_name--, count(column_name)
from completo_tablas
group by table_name
having count(column_name)=11
--)
Obteining, something like:
Table_name
--------------
table1
table2
.
.
.
The problem i cant solve, isn't getting the UNION of the tables with 11 columns for a specific day; I know i can do than copying the tables names like:
Select * from tabla1 UNION select * from tabla2 UNION Sel....
Given the nature of our business, the number of tables is going to increase over time.
What I want, cause of the nature of our business, is a "dynamic" query, where I don't have the names of the tables set by hand in the UNION query.
But something with which you can always get just that, the union of all tables with 11 columns
Thank you for your time.

Related

SQL select from several tables and output to several tables

I have several tables of which most contain distinct ID columns and most have an additional column containing dates.
Now I need to retrieve all IDs with their corresponding dates from all tables.
Is there a way to output all IDs and dates from all tables at once and without creating duplicates ?
You can use UNION ALL to combine multiple queries:
SELECT 'table_a' source, table_a_id id, creation_date FROM table_a
UNION ALL
SELECT 'table_b' source, table_b_id id, creation_date FROM table_b
UNION ALL
SELECT 'table_c' source, table_c_id id, creation_date FROM table_c;
If you need to remove duplicate rows, you can use UNION instead of UNION ALL, at the cost of some performance.

Union of multiple queries using the count function

I'm working on learning more about how the UNION function works in SQL Server.
I've got a query that is directed at a single table:
SELECT Category, COUNT(*) AS Number
FROM Table1
GROUP BY Category;
This returns the number of entries for each distinct line in the Category column.
I have multiple tables that are organized by this Category column and I'd like to be able to have the results for every table returned by one query.
It seems like UNION will accomplish what I want it to do but the way I've tried implementing the query doesn't work with COUNT(*).
SELECT *
FROM (SELECT Table1.Category
Table1.COUNT(*) AS Number
FROM dbo.Table1
UNION
SELECT Table2.Category
Table2.COUNT(*) AS Number
FROM dbo.Table2) AS a
GROUP BY a.Category
I'm sure there's an obvious reason why this doesn't work but can anyone point out what that is and how I could accomplish what I'm trying to do?
You cannot write a common Group by clause for two different select's. You need to use Group by clause for each select
SELECT TABLE1.Category, --missing comma here
COUNT(*) as Number -- Remove TABLE1. alias name
FROM dbo.TABLE1
GROUP BY Category
UNION ALL --UNION
SELECT TABLE2.Category, --missing comma here
COUNT(*) as Number -- Remove TABLE1. alias name
FROM dbo.TABLE2
GROUP BY Category
If you really want to remove duplicates in result then change UNION ALL to UNION
COUNT as any associated aggregation function has to have GROUP BY specified. You have to use group by for each sub query separately:
SELECT * FROM (
SELECT TABLE1.Category,
COUNT(*) as Number
FROM dbo.TABLE1
GROUP BY TABLE1.Category
UNION ALL
SELECT TABLE2.Category,
COUNT(*) as Number
FROM dbo.TABLE2
GROUP BY TABLE2.Category
) as a
It is better to use UNION ALL vs UNION - UNION eliminates duplicates from result sets, since - let say - you want to merge both results as they are it is safer to use UNION ALL

Select avg from each table

I would like to query multiple tables and get an average count of store_key from each, using a fairly elaborate set of WHERE criteria for each. I can query them all separately, but I'd like to do this in one query.
Each table has retailer_key, store_key (as well as many other columns)
I would like my query to return something that looks like:
Table Name | AVG # of store keys
Using a where condition similar to WHERE retailer_key = 41 AND... Using columns that each of these tables share.
Does that make any sense? It seems really simple, but for some reason I can't figure out how to build the query.
You could use a series of union all operators:
SELECT table_name, AVG(store_key)
FROM (SELECT 'table1' AS table_name, store_key, retailer_key
FROM table1
UNION ALL
SELECT 'table2' AS table_name, store_key, retailer_key
FROM table2
UNION ALL
SELECT 'table3' AS table_name, store_key, retailer_key
FROM table3
-- More queries like this if needed...
) t
WHERE retailer_key = 41 -- AND additional conditions
GROUP BY table_name

order by only one dataset of a union in a tsql union of datasets

I have the following problem.
Let TableA(Id int, Name nvarchar(200)) and TableB(Id int, Name nvarchar(200)).
If we run the following query:
SELECT *
FROM
(SELECT *
FROM TableA)
UNION
(SELECT *
FROM TableB)
we get the union of the two datasets.
My Problem is that I want the results of the second dataset to be the ordered by the Name column.
The reason why I need this, is the fact that TableA is a temporary table in my query, that always will hold one record, and this record I want to be the first in the resulting dataset from the union of the two datasets. Also, I want the multiple records of the TableB to be ordered by the Name column.
Unfortunately, when I try to execute the following query
SELECT *
FROM
(SELECT *
FROM TableA)
UNION
(SELECT *
FROM TableB
ORDER BY Name)
I get an ambiguous error message, that informs me that I have an incorrect syntax near the keyword order.
Thanks in advance for any help.
try this:
select id
, name
from
(select 1 as ordercol
, a.id
, a.name
from tableA
union
select 2 as ordercol
, b.id
, b.name
from tableB) i
order by ordercol, name
the error message resulted in you trying to union two subselects. you can put union between two selects that will then be put into a subselect. there is always a select after a union (or union all). i would also suggest you use a union all, that saves time because sql-server will otherwise try and remove records that are in both selects (which in this case is impossible due to the ordercol-column)
i have included a second order-by column that will order the first select before the second. if you order by that first and then by name, you should get the desired result.

SQL Append table queries

I have two tables, say table1 with two rows of data say row11 and row12
and table2 with 3 rows of data sat row21, row22, row23
Can anyone provide me with the SQL to create a query that returns
row11
row12
row21
row22
row23
Note: I dont want to create a new table just return the data.
Use UNION ALL, based on the example data:
SELECT * FROM TABLE1
UNION ALL
SELECT * FROM TABLE2
UNION removes duplicates - if both tables each had a row whose values were "rowx, 1", the query will return one row, not two. This also makes UNION slower than UNION ALL, because UNION ALL does not remove duplicates. Know your data, and use appropriately.
select * from table1 union select * from table2
Why not use a UNION?
SELECT
Col1,Col2,Col3
FROM
TABLE1
UNION
SELECT
Col1,Col2,Col3
FROM
TABLE2
Are the columns on the two tables identical?
In MS Access you can achieve the same goal with an INSERT INTO query:
INSERT INTO TABLE1 SELECT * FROM TABLE2;