Select avg from each table - sql

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

Related

PostgreSQL - UNION of tables based on number of columns

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.

SQL check or uniqueness in one column in multipe tables

I have a 'unique' column, 'GID_New' that is in multiple tables. Is there a way to check if it's unique across all the tables in the QGIS project in SQL?
Can it be done in one SQL search without merging the tables into one and then running something like
SELECT A.GID_New, count(*), A.TableName
FROM "Water_Merged" as A
Group by A.GID_New
And then checking for a count >1
I would like to know which table the non-unique GID_New's are from as well.
The data is in a geopackage in QGIS so the code needs to work in QGIS SQL implementation.
You can use union all:
select gid_new, count(*) no_matches
from (
select gid_new from table1
union all select gid_new from table2
union all select gid_new from table3
) t
group by gid
having count(*) > 1
If you want to know in which table duplicates exists, then one option is string concatenation. Assuming that your database uses string_agg(), that would look like:
select gid_new, count(*) no_matches, string_agg(which, ',') which_tables
from (
select 'table1' which, gid_new from table1
union all select 'table2', gid_new from table2
union all select 'table3', gid_new from table3
) t
group by gid
having count(*) > 1

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

Conditional count over multiple tables

Is there a simpler way to count the number of rows in different tables that fulfill the same conditions?
For example, I want to separately count the number of rows in the following two tables that correspond to certain IDs:
Select
'table1' as tablename, count(*) as rownr from table1
where SOMEID in ('1815972751','1815751159','1815752967','1815756079')
union all
Select
'table2' as tablename, count(*) as rownr from table2
where SOMEID in ('1815972751','1815751159','1815752967','1815756079') ;
The result would be something like
table1 | 21
table2 | 54
However, I would like to only define the condition (in this case, the IDs) once, for example in a variable or list, so they area easily manageable.
Here is one way:
select tablename, count(*)
from (select 'table1' as tablename, someid
from table1
union all
select 'table2' as tablename, someid
from table2
) t
where someid in ('1815972751', '1815751159', '1815752967', '1815756079')
group by tablename;
Do note that performance may not be as good as in your original version.

How to check if multiple tables have rows for given ID

I have master table with several details tables. I need to check if each of the details tables have any rows for given ID. Right now I am going through all the tables and checking if count>0 but there must be a better way.
SELECT COUNT(*) FROM Table1 WHERE ID=3;
SELECT COUNT(*) FROM Table2 WHERE ID=3;
...
SELECT COUNT(*) FROM TableN WHERE ID=3;
Is there a way to do this in one effective SQL statement?
WITH CTE AS
(
SELECT 'T1' AS Name, COUNT(*) AS Total FROM Table1 WHERE ID=3
UNION ALL
SELECT 'T2' AS Name, COUNT(*) AS Total FROM Table2 WHERE ID=3
UNION ALL
...
UNION ALL
SELECT 'Tn' AS Name, COUNT(*) AS Total FROM TableN WHERE ID=3;
)
Select * from CTE where Total > 0
This sounds like poor design of your tables. I think you need to either combine some tables or add a bridge table that you can query.
Or, keep querying the individual tables if you structure is optimal and just have your application deal with running each one.
If you really want one result set you can do:
DECLARE #ID INT
SET #ID = 3
SELECT 'Table1' TableName, COUNT(*) FROM Table1 WHERE ID=#ID;
UNION
SELECT 'Table2' TableName, COUNT(*) FROM Table2 WHERE ID=#ID;
UNION
...
UNION
SELECT 'TableN' TableName, COUNT(*) FROM TableN WHERE ID=#ID;
I don't see a way to not scan all tables if that's what you're trying to avoid.