I would like to find all the tables containing two particular separate columns in SQL Server.
The first column name is "LIKE '%A%'" (Meaning it contains the substring "A") and the second column name is "LIKE '%B%'" (Meaning it contains the substring "B").
I wrote the following query and I would like to check its correctness:
SELECT s.TABLE_NAME
FROM (SELECT COLUMN_NAME, TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%A%'
UNION
SELECT COLUMN_NAME, TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%B%') s
WHERE EXISTS (SELECT COLUMN_NAME, s.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%A%')
AND EXISTS (SELECT COLUMN_NAME, s.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%B%');
That should be easier:
SELECT s.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES AS s
WHERE s.TABLE_TYPE='BASE TABLE'
AND EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=s.TABLE_NAME AND COLUMN_NAME LIKE '%A%')
AND EXISTS (SELECT 1
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=s.TABLE_NAME AND COLUMN_NAME LIKE '%B%');
UPDATE
with this code you will find all columns fitting both criterias as a list...
SELECT s.TABLE_NAME,listA,listB
FROM INFORMATION_SCHEMA.TABLES AS s
CROSS APPLY (SELECT STUFF(
(
SELECT ', ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=s.TABLE_NAME AND COLUMN_NAME LIKE '%med%'
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
),1,2,'')
) AS columnsWithA(listA)
CROSS APPLY (SELECT STUFF(
(
SELECT ', ' + COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME=s.TABLE_NAME AND COLUMN_NAME LIKE 'kli%'
ORDER BY ORDINAL_POSITION
FOR XML PATH('')
),1,2,'')
) AS columnsWithB(listB)
WHERE s.TABLE_TYPE='BASE TABLE'
AND listA IS NOT NULL AND listB IS NOT NULL
UPDATE 2
And with a final AND listA<>listB AND CHARINDEX(',',listA)=0 you would exclude identical listA and listB as long as there is only one column (=> no comma)
Set logic to the rescue!
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE COLUMN_NAME LIKE '%A%'
AND COLUMN_NAME NOT LIKE '%B%'
INTERSECT
SELECT DISTINCT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS AS c
WHERE COLUMN_NAME LIKE '%B%'
AND COLUMN_NAME NOT LIKE '%A%'
Updated to mutually exclude double matches.
Removed inner join on TABLE schema
One method just uses aggregation and having:
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
GROPU BY TABLE_NAME
HAVING SUM(CASE WHEN COLUMN_NAME LIKE '%A%' THEN 1 ELSE 0 END) > 0 AND
SUM(CASE WHEN COLUMN_NAME LIKE '%B%' THEN 1 ELSE 0 END) > 0;
If necessary, you can use join back to INFORMATION_SCHEMA.COLUMNS to get the column names -- although that is not your actual question.
Related
SELECT column_key,
Column_name
FROM tableA
UNION
SELECT column_key,
Column_name
FROM tableB
WHERE Database_Name = 'PROD'
AND Table_Name = 'Document_Setup'
AND Column_Name IN
(
'App_Advice',
'Expect_Response_Time',
'Matching_Interchanges',
'Transmit')
Now I want to add new column check condition in second table when Doc_Standard_Name ='830' available then to add column name "Multiple_Transaction_Set" else it will work as what currently its working
But I don't want to write logic with two big if statement blocks. Can we implement with case Statement or other way?
SELECT
*
FROM Document_Standard
WHERE Document_key = #Document_key
AND Doc_Standard_Name IN ('830')
SELECT column_key,
Column_name
FROM tableA
UNION
SELECT column_key,
Column_name
FROM tableB
WHERE Database_Name = 'PROD'
AND Table_Name = 'Document_Setup'
AND Column_Name IN
(
'App_Advice',
'Expect_Response_Time',
'Matching_Interchanges',
'Transmit',
'Multiple_Transaction_Set')
I have written in this way, but don't want to write in if else block instead I want to handle this in a single block:
IF EXISTS
(
SELECT
*
FROM Document_Standard
WHERE Document_key = #Document_key
AND Doc_Standard_Name IN ('830')
)
BEGIN
SELECT column_key,
Column_name
FROM tableA
UNION
SELECT column_key,
Column_name
FROM tableB
WHERE Database_Name = 'PROD'
AND Table_Name = 'Document_Setup'
AND Column_Name IN
(
'App_Advice',
'Expect_Response_Time',
'Matching_Interchanges',
'Transmit')
END
ELSE
BEGIN
SELECT column_key,
Column_name
FROM tableA
UNION
SELECT column_key,
Column_name
FROM tableB
WHERE Database_Name = 'PROD'
AND Table_Name = 'Document_Setup'
AND Column_Name IN
(
'App_Advice',
'Expect_Response_Time',
'Matching_Interchanges',
'Transmit',
'Multiple_Transaction_Set')
END;
Just use some, OR logic:
SELECT column_key,
Column_name
FROM tableA
UNION --ALL --Should this is UNION? UNION is a significantly more expensive; it should only be used if you need DISTINCT rows
SELECT column_key,
Column_name
FROM tableA
WHERE Column_Name IN ('App_Advice', 'Expect_Response_Time', 'Matching_Interchanges', 'Transmit')
OR (EXISTS (SELECT 1
FROM Document_Standard
WHERE Document_key = #Document_key
AND Doc_Standard_Name IN ('830'))
AND Column_Name = 'Multiple_Transaction_Set');
I want output as get all tables from a database with name as 'T_'.
I have written the query ,it gets all the table name.
but I want no get the query as 'select count(*) from all tables in database union'
means I want to get
select count(*) from T1 UNION
select count(*) from T2 UNION
select count(*) from T3 UNION...
and so on
there are 1000 of rows so I want a query which will output the count(*) query itself.
select 'select count(*) from ' + table_name from INFORMATION_SCHEMA.TABLES where table_type='BASE TABLE'
and left(table_name,2) = 'T_'
order by TABLE_NAME
this query gives all select count(*) table names like T_*
select 'select count(*) from ' + table_name from INFORMATION_SCHEMA.TABLES where table_type='BASE TABLE'
and left(table_name,2) = 'T_'
order by TABLE_NAME
+'UNION';
Getting output
select count(*) from T_T1
select count(*) from T_T2
select count(*) from T_T3
expected output
select count(*) from T_T1 UNION
select count(*) from T_T2 UNION
select count(*) from T_T3 UNION
order by TABLE_NAME + ' UNION' means you want want to order by the value of TABLE_NAME with the sting UNION concatenated onto it (which will change nothing)
You need to put the UNION (I actually suggest UNION ALL here) in your SELECT: ...table_type='BASE TABLE' + N' UNION ALL '.
I also suggest changing table_name to QUOTENAME(table_name). Giving you a final query of:
SELECT N'SELECT COUNT(*) FROM' + QUOTENAME(TABLE_NAME) + NCHAR(13) + NCHAR(10) + N'UNION ALL'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND LEFT(TABLE_NAME, 2) = 'T_'
ORDER BY TABLE_NAME;
select 'select count(*) from ' + table_name + ' UNION ' from INFORMATION_SCHEMA ...
I have over 50 different tables which I would like to combine into one big table. All the tables have a different number of columns.
Currently, to union the tables together, I am writing an individual select statement for each of the tables, and inserting a null column if that column doesn't exist in the table. Then I am using UNION ALL to union them together.
For example:
(
select col1
, null as col2
, col3
from table1
union all
select col1
, col2
, null as col
from table2
)
Although this works, it is very manual and time consuming. Is there a better, more efficient way to union these tables into one? As with over 50 tables, I am going to have thousands of lines of code.
Thank you!
You can query SQL Server metadata, and from the result dynamically construct a SQL statement. This can be done in any programming language, including T-SQL itself.
Here's a rough example; execute this query, copy/paste the result back into the query window, and execute that.
If the 50 tables have similar names (e.g. all start with Foo), then you can replace the exhaustive table list (WHERE TABLE_NAME IN ('table1', 'table2', 'table3') in my example) by WHERE TABLE_NAME LIKE 'Foo%'.
WITH
AllTables (TABLE_NAME) AS (
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME IN ('table1', 'table2', 'table3')
),
TablesWithSelectors (TABLE_NAME, COLUMN_NAME, Selector) AS (
SELECT t.TABLE_NAME, a.COLUMN_NAME, CASE WHEN b.COLUMN_NAME IS NULL THEN 'NULL AS ' ELSE '' END + a.COLUMN_NAME
FROM AllTables t
CROSS JOIN (SELECT DISTINCT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME IN (SELECT TABLE_NAME FROM AllTables)) a
LEFT OUTER JOIN INFORMATION_SCHEMA.COLUMNS b ON b.TABLE_NAME = t.TABLE_NAME AND b.COLUMN_NAME = a.COLUMN_NAME
),
SelectStatements (Sql) AS (
SELECT
'SELECT ' +
STUFF((
SELECT ', ' + Selector
FROM TablesWithSelectors
WHERE TABLE_NAME = r.TABLE_NAME
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
, 1, 2, '') +
' FROM ' +
TABLE_NAME
FROM TablesWithSelectors r
GROUP BY TABLE_NAME
)
SELECT STUFF((
SELECT ' UNION ALL ' + sql
FROM SelectStatements
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)'), 1, 11, '')
Thanks to:
How to use GROUP BY to concatenate strings in SQL Server?
I want to a search for all tables that includes both of 'Documentversionid' and 'ClientMedicationID' columns.
Try this:
SELECT t1.TABLE_NAME
FROM
(
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%Documentversionid%'
) t1
INNER JOIN
(
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME LIKE '%ClientMedicationID%'
) t2
ON t1.TABLE_NAME = t2.TABLE_NAME
This should do it:
SELECT COUNT(*) as COUNT, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME
FROM `information_schema`.`columns`
WHERE `TABLE_SCHEMA`='<YOUR DATABASE>' AND
(`COLUMN_NAME` = 'Documentversionid' OR `COLUMN_NAME`='ClientMedicationID')
GROUP BY `TABLE_NAME` HAVING COUNT > 1
Database abc and it contains 2 tables table1 and table2.
I would like to have something like this:
table1
column1 int
column2 nvarchar(50)
table2
column1 int
column2 money
column3 bit
Use the INFORMATION_SCHEMA schema and the objects within it like
INFORMATION_SCHEMA.COLUMNS
which has all of that metadata you need to produce the output you want.
Try use INFORMATION_SCHEMA.COLUMNS
select * from INFORMATION_SCHEMA.COLUMNS
where TABLE_CATALOG='My_Database_Name_Here'
or
select TABLE_NAME,COLUMN_NAME,DATA_TYPE from INFORMATION_SCHEMA.COLUMNS
where TABLE_CATALOG='My_Database_Name_Here'
You could just write a query something like this:
USE abc --change this to whatever database you have your tables in
SELECT Table_Name
,Column_Name
,DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME IN ('table1','table2')
SELECT
TABLE_NAME, COLUMN_NAME as [Column],
ISNULL(DATA_TYPE + '(' + cast(CHARACTER_MAXIMUM_LENGTH as nvarchar(10)) +')', DATA_TYPE) as [Data type]
FROM
information_schema.COLUMNS