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
Related
I need help in SQL Server, I want to get the number of identical values from a column, but I only have column names, here is my script
select
column_name, table_name, data_type, d.name, d.description
from
INFORMATION_SCHEMA.COLUMNS
inner join
Dims d on table_name = 'Dim_' + d.name + '_View'
where
column_name = 'ExtCode'
group by
column_name, table_name, data_type, d.name, d.description
having
count(column_name) > 1;
I want to get the number of records in column names that are greater than 1
I think you are trying to do two things with one SQL:
Find all the column names that are repeated across tables
Display each occurrence of it along with the table they occur in. Break this up into two parts.
Start with a list of repeated column names:
Select column_name From INFORMATION_SCHEMA.COLUMNS
Where table_name like 'Dim%View'
Group By column_name Having count(*)>1
Then join that to your query to retain only the columns that appear more than once:
select
Cols.column_name, cols.table_name, cols.data_type, d.name, d.description
from INFORMATION_SCHEMA.COLUMNS cols inner join Dims d
on table_name = 'Dim_' + d.name + '_View'
Inner Join (
Select column_name From INFORMATION_SCHEMA.COLUMNS
Where table_name like 'Dim%View'
Group By column_name Having count(*)>1
) multi On multi.column_name=cols.column_name
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.
I’m a beginner to SQL and am struggling with the following:
I have two tables with the same columns except one column from table A is not a column of table B and table B has a column that table A doesn’t have. I want to copy data from
one into the other table.
I got the following SQL, that gives me the column-names of my table B:
SELECT name
FROM sys.columns
WHERE object_id = OBJECT_ID(’TABLEB’)
AND name <> COLUMNNOTINA
I want to use that select as a query:
SELECT
(SELECT name
FROM sys.columns
WHERE object_id = OBJECT_ID(’TABLEB’)
AND name <> COLUMNNOTINA), 0
FROM
TABLEA
This does not work, but how do I make this work?
Thank you in advance!
Let's say there is some common thing connecting the two tables
For example, ORDINAL_POSITION
T1.ORDINAL_POSITION = T2.ORDINAL_POSITION
Is there a description or property to compare each column?
select * from (
(SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(’TABLEA’) ) as T1
Inner join
(SELECT name FROM sys.columns WHERE object_id = OBJECT_ID(’TABLEB’) ) as T2
ON T1.ORDINAL_POSITION = T2.ORDINAL_POSITION
)
Where T1.ColName <> T2.ColName
I'm working with two very wide, very similar tables in SQL Server. Anywhere from 5-10 columns exist in one table but not in the other. Is there an easy way to find out which columns exist in one table but not in the other?
Use information_schema.columns. Here is one method with a full outer join:
select c1.column_name, c2.column_name
from (select c.*
from information_schema.columns
where table_name = #table1 and table_schema = #schema1
) c1 full outer join
(select c.*
from information_schema.columns
where table_name = #table2 and table_schema = #schema2
) c2
on c1.column_name = c2.column_name
where c1.column_name is null or c2.column_name is null
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')