How to select the name of the table in an SQL query? - sql

I'm using a UNION and a LIMIT to select the earliest occurence of a type of table row from multiple tables. I need a record of which table satisfied the query in the result set.
Is there a way of doing something like:
SELECT id, someField, tableName FROM someUnknownTable WHERE someConditions = true

You can select your tableName as a constant value:
Select id, someField, 'Table1' As tableName
From table1
Union
Select id, someField, 'Table2' As tableName
From table2
The second alias (As tableName) can be omitted.

Related

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

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.

Count rows in more than one table with tSQL

I need to count rows in more than one table in SQL Server 2008. I do this:
select count(*) from (select * from tbl1 union all select * from tbl2)
But it gives me an error of incorrect syntax near ). Why?
PS. The actual number of tables can be more than 2.
In case you have different number of columns in your tables try this way
SELECT count(*)
FROM (
SELECT NULL as columnName
FROM tbl1
UNION ALL
SELECT NULL
FROM tbl2
) T
try this:
You have to give a name to your derived table
select count(*) from
(select * from tbl1 union all select * from tbl2)a
I think you have to alias the SELECT in the FROM clause:
select count(*)
from
(
select * from tbl1
union all
select * from tbl2
) AS SUB
You also need to ensure that the * in both tables tbl1 and tbl2 return exactly the same number of columns and they have to be matched in their type.
I don't like doing the union before doing the count. It gives the SQL optimizer an opportunithy to choose to do more work.
AlexK's (deleted) solution is fine. You could also do:
select (select count(*) from tbl1) + (select count(*) from tbl2) as cnt

Order by tablename?

Is there any way to use the "order" function on your table name. i.e I want to union two tables then sort by the one column, then by table name.
Add constant to your column list that describes your table name, E.g.
select *, 'TableA' as TableName
from TableA
union all
select *, 'TableB' as TableName
from TableB
order by TableName
You can create a separate column (assuming that your columns are col1 and col2)
select col1,col2,table_1 as table_name
from table_1
union
select col1,col2,table_2 as table_name
from table_2
order by col1,table_name;

Returning table type in table union in SQL

I have union of two tables, these tables don't have column type, but I need to return table name (or similar identification) so I can know in my code which table it was from. I'm using Microsoft SQL Server 2008 R2.
Here is my current SQL, that doesn't return type yet.
select Id, Name, CHAR(0) as Type
from Table1
union all
select Id, Name, CHAR(1) as Type
from Table2;
The solution:
select Id, Name, 'Table_1' as Type from Table1
union all
select Id, Name, 'Table_2' as Type from Table2;
How about this:
select 'Table1' as Type, Id, Name from Table1
union all select 'Table2' as type, Id, Name from Table2;