In this answer, you can search all tables for a column by column name.
Say I have a list of columns like this:
DECLARE #columnNames TABLE (Id varchar(30))
INSERT INTO #columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
I want to find all tables that have at least these three columns. Is it possible to do a foreach loop with the code below, or is there a simpler way?
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name #xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName'
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME LIKE '#xColumnName'
ORDER BY
TableName, ColumnName;
The table must have all 3 colums named in the list, and it would be cool if I could filter out tables that do not have a certain column or list of columns
This is a relational division question. There are a few methods to solve this as Joe Celko writes. The common solution is as follows:
DECLARE #columnNames TABLE (Id varchar(30))
INSERT INTO #columnNames
VALUES ('xColumn1Name'), ('xColumn2Name'), ('xColumn3Name')
select t.name
from sys.tables t
join sys.columns c on c.object_id = t.object_id
join #columnNames cn on cn.Id = c.name
group by t.object_id, t.name
having count(*) >=
(select count(*) from #columnNames);
What this says is: give me all tables, where the number of columns which match the list #columnName is the same or more as the number in that list, in other words tehre is a match for every column.
This should get your initial goal.
SELECT
[TableName]
FROM (
SELECT
COLUMN_NAME AS 'ColumnName', -- this code will get all tables with a column by name #xColumnName, but I would like to pass in a list
TABLE_NAME AS 'TableName',
ROW_NUMBER() OVER(PARTITION BY TABLE_NAME ORDER BY COLUMN_NAME) rn
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE
COLUMN_NAME IN ('xColumn1Name', 'xColumn2Name', 'xColumn3Name')
) a
WHERE rn >= 3
For a short explanation, this query will look through the information schema to find any of these columns in a table. The ROW_NUMBER() then basically groups the columns by table. If there are 3 or more results (rn) then all 3 columns are there.
Since it is a sub select, you can also filter the outside select for particular columns if you want.
You could use INTERSECT to combine different result sets. This will give the records that are in all result sets, so in this case, the tables that have all three columns.
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn1Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
INTERSECT
SELECT OBJECT_NAME(object_id) AS Table
FROM sys.columns
WHERE name = 'xColumn3Name'
Related
This question already has answers here:
How can I get column names from a table in SQL Server?
(22 answers)
Closed 3 years ago.
I've a database with huge number of tables. From these tables I want to list out all the column names that are appearing in more than one table along with the their table names.
I tried google search to find any suitable article that can explain how to achieve the results that I've described in the problem section.
No code snippets
No error messages.
This will return the column names and the table names:
select distinct
TABLE_NAME,
COLUMN_NAME
from INFORMATION_SCHEMA.COLUMNS where COLUMN_NAME in(
select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS
group by COLUMN_NAME
having count(*) > 1
)
order by TABLE_NAME, COLUMN_NAME
There are a lot of results and snippets that show how to get all column names in a database. It's a single query to sys.columns, eg :
select Name
from sys.columns
The same SQL queries that return multiple occurences in any table can be used here too, eg :
select Name,count(*)
from sys.columns
group by Name
having count(*)>1
Will return column names that occur more than once.
You can get the column and table names without joining by using COUNT() with OVER :
with t as (
select name,
object_name(object_id) as TableName,
count(*) over (partition by name) cnt
from sys.columns
)
select *
from t
where cnt >1
The query below will return the column name along with the number of its occurences in the current database tables:
SELECT c.NAME AS 'ColumnName', COUNT(*) AS Occurences
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
GROUP BY c.NAME
HAVING COUNT(*) > 1
This query below will help to identify the specific column name is placed in which tables:
-- Find column name in all the tables
SELECT c.NAME AS 'ColumnName', t.NAME AS 'TableName'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.NAME LIKE '%columnname%' -- to be searchable column name
ORDER BY TableName, ColumnName;
Like we had query to find no of columns in a Table, is there any similar query to find total no of columns in a Sql Server View ?
Even simpler is to use sys.columns.
select count(*)
from sys.columns
where OBJECT_ID = OBJECT_ID('YourView')
Similar to Larnu's comment, I tend to prefer the Table-Valued-Function
Example
Declare #tsql nvarchar(max) = N'Select * from YourView_Table_Or_Query'
Select column_ordinal
,name
,system_type_name
From sys.dm_exec_describe_first_result_set(#tsql,null,null )
-- Or for the Count
Select ColumnCnt=count(*)
From sys.dm_exec_describe_first_result_set(#tsql,null,null)
Besides the rather clumsy procedure sp_describe_first_reuslt_set you can use the generic abilities of XML:
SELECT (SELECT TOP 1 * FROM YourView FOR XML RAW, ELEMENTS XSINIL ,TYPE).value('count(/row/*)','int');
Edit: Forgot to add ELEMENTS XSNIL which would omit columns with a value of NULL otherwise...
--this might help
SELECT v.name, count(1) ColumnCount
FROM SYS.VIEWS v
INNER JOIN SYS.all_columns c ON v.object_id = c.object_id
WHERE v.name IN (SELECT name FROM sys.VIEWS)
GROUP BY v.name
ORDER BY v.name
SELECT name
FROM sys.VIEWS, can be replaced by viewname/s or query which returns viewname/s
How do I retrieve all record from every table (Ex: table1, table2, table3, ... tableN ) where id = 1 from single database (EX: database1) in SQL Server 2008 R2?
Let's suppose I have 1 database and in that I have infinite tables (EX. table1,table2, ....,tableN). Is this possible to get all the record from entire database where id=1 on each table? I think it is possible with SQL information_schema.table or information_schema.column, but I don't know how to use this.
Any help appreciated
Thanks in advance!
You can use the undocumented sp_msforeachtable
sp_msforeachtable
#command1 = 'SELECT * FROM ? WHERE id=1',
#whereand = ' And Object_id In (Select Object_id From sys.columns Where name=''id'')'
#command1 is your query. The question mark is a placeholder the stored procedure uses to insert the table name.
#whereand limits the search to just tables that have the column named id
I don't have much idea of MySQL, Use this in db2
Select C.NAME,C.ROLLNUMBER from TABLE1 C,TABLE2 A where C.ROLLNUMBER=A.ROLLNUMBER and id = 1 order by C.CIRCLENAME
hope this will work too..
If you want to mention the tables manually try this.
SELECT COL1,COL2,COL3....COLN FROM TABLE1 WHERE ID=1
UNION ALL
SELECT COL1,COL2,COL3....COLN FROM TABLE2 WHERE ID=1
UNION ALL
SELECT COL1,COL2,COL3....COLN FROM TABLE2 WHERE ID=1
:
:
:
UNION ALL
SELECT COL1,COL2,COL3....COLN FROM TABLEN WHERE ID=1
Note: The col1,col2,col3...coln Should Be Same Datatype in All The Mentioned Tables
This for dynamic building of all the tables with id =1
SELECT STUFF((SELECT '
UNION ALL
SELECT COL1,COL2,COL3..COLN FROM '+TABLE_NAME + ' WHERE ID=1 '
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' FOR XML PATH(''),type).value('.', 'NVARCHAR(MAX)'),1,11,'')
Note:Your tables must contain the common column i.e ID .change the column names as per you need but all the mentioned columns in select statement should be contain in all of your tables.
The best possible way would be to generate a dynamic query and executed it to get the required information.
To generate the query you can use the schema information related system tables and feed the data in a fixed format table. i.e. make a fix format tables having a defined column structure. That will help to feed the data.
For example:
CREATE TABLE AllTableData
(
TableId int,
TableName nvarchar(250),
TableData NVARCHAR(max),
SelectedId int
)
Where TableId is the id of table from system table and TableData will contain the concatenated value string of all columns of a table with some separator identifier.
;WITH T AS
(
SELECT
T1.*
FROM
INFORMATION_SCHEMA.TABLES T1
INNER JOIN INFORMATION_SCHEMA.COLUMNS T2 ON T2.TABLE_NAME = T2.TABLE_NAME
WHERE
T2.COLUMN_NAME = 'Id'
AND T1.TABLE_TYPE='BASE TABLE'
),
DynamicQuery AS (
SELECT
1 AS Id,
CONCAT(
'SELECT ', QUOTENAME(T.TABLE_NAME,''''),' AS [TableName],',
CONCAT(' CONCAT(',STUFF((SELECT CONCAT(', [' , C.COLUMN_NAME,']' )
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE C.TABLE_NAME = T.TABLE_NAME
FOR XML PATH('')), 1, 1, ''),') AS [TableData]'
)
,', 1 AS [SelectedId] FROM ', T.TABLE_NAME,' WHERE Id = 1'
) [FinalString]
FROM T
)
SELECT DISTINCT
STUFF((SELECT ' UNION ALL ' + DQ2.FinalString
FROM DynamicQuery DQ2
WHERE DQ2.Id = DQ1.Id
FOR XML PATH('')), 1, 10, '') [FinalString]
FROM DynamicQuery DQ1
GROUP BY DQ1.Id, DQ1.FinalString
I think, this is what you are searching for.
I have many tables in my database. I want to create a general query which will search for duplicate records in all columns of all the tables in a database in SQL server.
Something like this,
select
T.NAME as TABLE_NAME,
C.NAME as COLUMN_NAME
from
SYS.TABLES as T
inner join
SYS.COLUMNS C on T.OBJECT_ID = C.OBJECT_ID
group by
T.NAME, C.NAME
having
count(*) > 1
I do not know how to do it or if there is any way to do it.
You can find duplicate column names with something like this:
select column_name
from information_schema.columns
group by column_name
having count(*) > 1;
You can join back to column to get the table names. You might also want to limit the search to base tables (it is unclear what you mean by "duplicates").
If you want a quick way to see if two tables are the same you can start with CHECKSUM_AGG and compare the results against two tables. If they have the same columns types and the results of checksum_agg are equal the contents are the same regardless of the row order.
I need to display the table name in the select statement. how?
exact question:
we have common columns in two tables. we are displaying the records by using
select column_name from table_name_1
union
select column_name from table_name_2
But the requirement is, we need to display the source table_name along with the data.
consider a,c are present in table_1 and b,d are present in table_2.
we need the output in the following way
eg:
column_name table_name
a table_1
b table_2
c table_1
d table_2
.......................................................
......................................................
Is this possible
select 'table1', * from table1
union
select 'table2',* from table2