Search table names that has 3 exact columns - sql

What's wrong with the below script? I am trying to locate all the tables that has the following column names: ItemID, QueryID, and CurrencyID. Currently, it only gives me tables that has 2 columns out the 3 mentioned so one of the column will be missing.
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME in ('ItemID', 'QueryID', 'CurrencyID')
GROUP BY TABLE_NAME
HAVING COUNT(*) = 2;

If you want all 3 to match as well as 2, why don't you use
HAVING COUNT(*) >= 2;

SELECT t.name
FROM sys.tables t INNER JOIN sys.columns c
ON t.object_id = c.object_id
WHERE c.name IN ('ItemID', 'QueryID', 'CurrencyID')
GROUP BY t.name
HAVING COUNT(DISTINCT c.name) >= 3

Alternate answer to avoid > / = / >= issues:
This will only return a table when all 3 are found, but wallyk's answer is spot on given your question... choose his if it works for you.
SELECT T.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES T
WHERE EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C1 WHERE T.TABLE_NAME=C1.TABLE_NAME AND C1.COLUMN_NAME='ItemID')
AND EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C2 WHERE T.TABLE_NAME=C2.TABLE_NAME AND C2.COLUMN_NAME='QueryID')
AND EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS C3 WHERE T.TABLE_NAME=C3.TABLE_NAME AND C3.COLUMN_NAME='CurrencyID')

Related

Simple SQL Server syntax assistance please

I'm banging my head against the wall with this one. Why does the query editor in SSMS give me an error about the closing parenthesis at the end of this query?
SELECT
c.TABLE_NAME,
c.COLUMN_NAME
FROM
INFORMATION_SCHEMA.COLUMNS c
INNER JOIN
(SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
GROUP BY COLUMN_NAME
HAVING COUNT(*) = 1)
I get this error:
Incorrect syntax near ')'
You're missing an alias for the subquery in parenthesis and an on clause:
SELECT
c.TABLE_NAME,
c.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS c
INNER JOIN
(SELECT
COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
GROUP BY COLUMN_NAME
HAVING COUNT(*) = 1
) x -- Alias added here
ON x.COLUMN_NAME = c.COLUMN_NAME -- ON caluse
You don't need to use join here, you can use exists :
select c.*
from information_schema.columns c
where not exists (select 1
from information_schema.columns c1
where (c1.column_name = c.column_name) and
(c1.table_name <> c.table_name or c1.table_schema <> c.table_schema)
);

How to also retrieve row/record count from following DB2 query?

Need to also select the total record count given the following query. How would I go about doing this?
SELECT DISTINCT t.Creator AS TABLE_SCHEMA, t.Name AS Table_Name, c.Name AS COLUMN_NAME,
c.COLTYPE AS DATA_TYPE, CASE WHEN c.KEYSEQ = 1 THEN 'Primary Key' ELSE NULL END AS CONSTRAINT_TYPE, NULL AS DATA_PRECISION, NULL AS DATA_SCALE
FROM SYSIBM.SYSTABLES t
INNER JOIN SYSIBM.SYSCOLUMNS c ON c.TBNAME = t.Name
WHERE t.Creator='MY_SCHEMA_NAME' AND t.Name='MY_TABLE_NAME'
Any help would be appreciated, thanks
For any SELECT statement including your one:
SELECT T.*, COUNT(1) OVER() AS ROW_COUNT
FROM
(
SELECT DISTINCT t.Creator AS TABLE_SCHEMA, t.Name AS Table_Name, c.Name AS COLUMN_NAME,
c.COLTYPE AS DATA_TYPE, CASE WHEN c.KEYSEQ = 1 THEN 'Primary Key' ELSE NULL END AS CONSTRAINT_TYPE, NULL AS DATA_PRECISION, NULL AS DATA_SCALE
FROM SYSIBM.SYSTABLES t
INNER JOIN SYSIBM.SYSCOLUMNS c ON c.TBNAME = t.Name
WHERE t.Creator='MY_SCHEMA_NAME' AND t.Name='MY_TABLE_NAME'
) T;
Need to also select the total record count given the following query.
The SELECT DISTINCT seems superfluous. The system tables should not have duplicates. If you are getting duplicates, it is probably because the JOIN conditions are not complete -- you should join on both the table name and creator.
So just use COUNT(*)
SELECT COUNT(*)
FROM SYSIBM.SYSTABLES t INNER JOIN
SYSIBM.SYSCOLUMNS c
ON c.TBNAME = t.Name AND
c.TBCREATOR = t.TBCREATOR
WHERE t.Creator = 'MY_SCHEMA_NAME' AND
t.Name = 'MY_TABLE_NAME';

search for multiple columns in a single table sql

I am using SQL Server 2017. How can I search for multiple column names in a single table?
I can search for a single column name (USERID) in my database with:
select *
from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME like '%USERID%'
order by TABLE_NAME
But, I want to search for all tables that have both USERID and DOB.
Using:
select *
from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME like '%USERID%' OR COLUMN_NAME like '%DOB%'
order by TABLE_NAME
returns a list of all tables that contain the column USERID as well as all tables that contain DOB.
Changing to AND results in a completely empty list, which is correct, as a single column would not contain both terms
You can try below -
select TABLE_NAME from INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME like '%USERID%' OR COLUMN_NAME like '%DOB%'
group by TABLE_NAME
having count(distinct COLUMN_NAME)=2
Below query will give you desired results:
;WITH cte
AS (SELECT object_id , ROW_NUMBER() OVER(PARTITION BY object_id
ORDER BY object_id) AS rn
FROM sys.columns AS c
WHERE c.name = 'USERID'
OR
c.name = 'DOB')
SELECT s.name + '.' + t.name
FROM sys.tables AS t INNER JOIN cte AS c ON t.object_id = c.object_id
INNER JOIN sys.schemas AS s ON t.schema_id = s.schema_id
WHERE c.rn > 1;
Please note to use exact column names with = operator and not like operator to get the correct results.

How to use INFORMATION_SCHEMA to find common fields between 2 tables?

For example, if I need to join TableA & TableB - how can I use the INFORMATION_SCHEMA database to find the common field between them?
Here is one method:
select column_name
from information_schema.columns c
where table_name in ('A', 'B')
group by column_name
having count(*) = 2;
If necessary, you should also include table_schema to identify the tables.
Another way to get common fields in two table:
SELECT C.name
FROM SYS.OBJECTS O
JOIN SYS.COLUMNS C
ON O.object_id = C.object_id
WHERE O.name IN
(
'TABLE-A', 'TABLE-B'
)
group by C.name
having count(*) = 2;
Way to get common column in two table:
SELECT A.COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS A
JOIN INFORMATION_SCHEMA.COLUMNS B ON A.COLUMN_NAME = B.COLUMN_NAME
WHERE A.TABLE_NAME 'Table_1'
AND B.TABLE_NAME = 'Table_2'

Finding all tables with matching columns

I have 81 tables where I want to find matching columns and output a list like:
"columnName" found in 3 tables:
table1
table2
table3
"columnName2" found in 4 tables:
table1
table3
table4
table5
The table INFORMATION_SCHEMA.COLUMNS is a system table which contains all columns for all tables. You can look at it by selecting from it.
For your question, you should try this :
select I.Column_name,
table_name,
table_count
from INFORMATION_SCHEMA.COLUMNS I
inner join
(
Select Column_name,
count(*) as table_count
from INFORMATION_SCHEMA.COLUMNS
group by Column_name) as T on T.Column_name = I.Column_name
You will have a table with, for each column_name, the tables, and the count in the column table_count.
I ust don't know how to output a list. You should put it on excel then if you want to format it I guess ..
Tell me if you have problem !
Below Query should give you the desired result. Let me know if you face any issues. You can modify script if you want to be specific about the single database
This query provides you Column Name - Concatinated Table Names - Number of Tables
SELECT t.CNAME AS ColumnName, STUFF(
(SELECT ',' + S.TNAME
FROM
(
SELECT C.NAME AS CNAME , T.NAME AS TNAME
FROM SYS.OBJECTS AS T
JOIN SYS.COLUMNS AS C
ON T.OBJECT_ID=C.OBJECT_ID
WHERE T.TYPE_DESC='USER_TABLE'
)s
WHERE s.CNAME = t.CNAME
FOR XML PATH('')),1,1,'') AS TablesUsed,
COUNT(t.TNAME)
FROM
(
SELECT C.NAME AS CNAME , T.NAME AS TNAME
FROM SYS.OBJECTS AS T
JOIN SYS.COLUMNS AS C
ON T.OBJECT_ID=C.OBJECT_ID
WHERE T.TYPE_DESC='USER_TABLE'
)t
GROUP BY t.CNAME
HAVING COUNT(t.TNAME) > 1
ORDER BY COUNT(t.TNAME) DESC