SQL column exist and not exist - sql

In my DB test, I have 400 tables.I would like to know in what table the column ID exists and in which tables the column ID does not exist. (see the pic)
I tryed with this query, but doesn't work. What's the best way ?
SELECT COLUMNS.TABLE_NAME, 'Yes' As MyCol_ID
FROM INFORMATION_SCHEMA.COLUMNS COLUMNS,
INFORMATION_SCHEMA.TABLES TABLES
WHERE COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
AND Upper(COLUMNS.COLUMN_NAME) = Upper('ID')
AND TABLES.TABLE_TYPE='BASE TABLE'
order by COLUMNS.TABLE_NAME
UNION
SELECT COLUMNS.TABLE_NAME, 'No' As MyCol_ID
FROM INFORMATION_SCHEMA.COLUMNS COLUMNS,
INFORMATION_SCHEMA.TABLES TABLES
WHERE COLUMNS.TABLE_NAME = TABLES.TABLE_NAME
AND Upper(COLUMNS.COLUMN_NAME) <> Upper('ID')
AND TABLES.TABLE_TYPE='BASE TABLE'
order by COLUMNS.TABLE_NAME

One method is basically a left join:
select t.table_schema, t.table_name,
(case when c.column_name is null then 'no' else 'yes' end) as id_exists
from information_schema.tables t left join
information_schema.columns c
on t.table_name = c.table_name and t.table_schema = c.table_schema and
c.column_name = 'ID'
where t.table_type = 'BASE_TABLE';
Notice that I fixed the join to include the schema name as well as the table name.

I like using the sys. variants. Run this in the context of your test DB:
SELECT T.NAME, CASE WHEN C.NAME = 'my_ColID' THEN 'YES' ELSE 'NO' END
FROM SYS.TABLES T
LEFT JOIN SYS.COLUMNS C ON C.object_id = T.object_id
AND C.NAME = 'my_ColID'
ORDER BY T.NAME

Related

How to get uncommon columns in 2 tables using left joins and information_schema.columns?

There are 2 tables which have 10 columns common in both the tables and 2 columns exist in table 2 but not in table 1. I have a task where I need to get those 2 columns present in Table 2 but not in Table 1.
The condition for the query is:
We must use information_schema.columns table.
Left join must be used on the same table information_schema.columns
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS t2
LEFT JOIN INFORMATION_SCHEMA.COLUMNS t1
ON t2.COLUMN_NAME = t1.COLUMN_NAME
AND t1.TABLE_NAME = 'table1'
WHERE t2.TABLE_NAME = 'table2'
AND t1.COLUMN_NAME IS NULL;
As per your requirement there care multiple solutions to this problem. Just giving a simple one:
Left join the information_schema.columns table with itself on the table_name and column_names and then filter out the columns of 'table1' using where not exists from the joined result. Finally apply another filter on the joined result to take only the column_name which are in 'table2':
select isc1.column_name from information_schema.columns isc1
left join information_schema.columns isc2
on isc1.table_name = isc2.table_name and isc1.column_name = isc2.column_name
where not exists (select column_name
from information_schema.columns isc
where isc.table_name = 'table1')
and isc1.table_name = 'table2';
A simple way is to take all the columns of Table 2 that are not in Table 1.
SELECT c.COLUMN_NAME
FROM information_schema.tables t
join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_NAME = c.TABLE_NAME
WHERE t.TABLE_NAME = 'table2' and c.COLUMN_NAME not in
(
SELECT c.COLUMN_NAME
FROM information_schema.tables t
join INFORMATION_SCHEMA.COLUMNS c on t.TABLE_NAME = c.TABLE_NAME
WHERE t.TABLE_NAME = 'table1'
)

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';

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'

information_schema views returning multiple rows per column

I'm trying to write a query which will give me certain key information about a given database's columns, but thus far my query seems to return some strange results! I need to know things about column sizes, nullability, uniqueness etc.
So why do I get multiple results per column?
SELECT
C.COLUMN_NAME AS COLUMN_NAME,
C.TABLE_NAME AS TABLE_NAME,
C.CHARACTER_MAXIMUM_LENGTH AS CHARACTER_MAXIMUM_LENGTH,
C.COLUMN_DEFAULT AS COLUMN_DEFAULT,
C.DATA_TYPE AS DATA_TYPE,
C.IS_NULLABLE AS IS_NULLABLE,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_PRIMARY_KEY,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'UNIQUE'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_UNIQUE,
C.NUMERIC_PRECISION AS NUMERIC_PRECISION,
C.NUMERIC_SCALE AS NUMERIC_SCALE,
FK.TABLE_NAME AS FOREIGN_KEY_TABLE_NAME,
FK.COLUMN_NAME AS FOREIGN_KEY_COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CC
ON C.COLUMN_NAME = CC.COLUMN_NAME
AND C.TABLE_NAME = CC.TABLE_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
ON CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
ON TC.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FC
ON RC.UNIQUE_CONSTRAINT_NAME = FC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FK
ON FC.COLUMN_NAME = FK.COLUMN_NAME
AND FC.TABLE_NAME = FK.TABLE_NAME
WHERE COLUMNPROPERTY(OBJECT_ID(C.TABLE_SCHEMA + '.' + C.TABLE_NAME), C.COLUMN_NAME, 'IsComputed') = 0
AND TC.CONSTRAINT_TYPE = 'FOREIGN KEY'
You probably have more than one constraint per column, hence if you join with the views containing constraint info, you get multiple rows, one for each constraint on the column.
Another reason could be that the same column and table name appears in different schemas.
You can check for the duplicates with the following query, which just shows you the columns appearing more than once:
WITH a as(
SELECT
C.COLUMN_NAME AS COLUMN_NAME,
C.TABLE_NAME AS TABLE_NAME,
C.CHARACTER_MAXIMUM_LENGTH AS CHARACTER_MAXIMUM_LENGTH,
C.COLUMN_DEFAULT AS COLUMN_DEFAULT,
C.DATA_TYPE AS DATA_TYPE,
C.IS_NULLABLE AS IS_NULLABLE,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'PRIMARY KEY'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_PRIMARY_KEY,
CASE WHEN EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE = 'UNIQUE'
AND CONSTRAINT_NAME = CC.CONSTRAINT_NAME) THEN 1 ELSE 0 END AS IS_UNIQUE,
C.NUMERIC_PRECISION AS NUMERIC_PRECISION,
C.NUMERIC_SCALE AS NUMERIC_SCALE,
FK.TABLE_NAME AS FOREIGN_KEY_TABLE_NAME,
FK.COLUMN_NAME AS FOREIGN_KEY_COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS C
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CC
ON C.COLUMN_NAME = CC.COLUMN_NAME
AND C.TABLE_NAME = CC.TABLE_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
ON CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
ON TC.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FC
ON RC.UNIQUE_CONSTRAINT_NAME = FC.CONSTRAINT_NAME
LEFT OUTER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE FK
ON FC.COLUMN_NAME = FK.COLUMN_NAME
AND FC.TABLE_NAME = FK.TABLE_NAME
WHERE COLUMNPROPERTY(OBJECT_ID(C.TABLE_SCHEMA + '.' + C.TABLE_NAME), C.COLUMN_NAME, 'IsComputed') = 0
AND TC.CONSTRAINT_TYPE = 'FOREIGN KEY'
), b as (
SELECT COLUMN_NAME, TABLE_NAME
FROM a
GROUP BY COLUMN_NAME, TABLE_NAME
HAVING count(*) > 1
)
SELECT a.*
FROM a JOIN b ON a.COLUMN_NAME = b.COLUMN_NAME AND a.TABLE_NAME = b.TABLE_NAME
The CTE a is exactly your query from above.
Whenever you add a JOIN to a query, there is the possibility that that relationship will be one-to-many, and thus multiply out the results. You have 5 JOINs here, so presumably one of them has fallen into this case.
My guess would be that multiple constraints can apply to a single column, and you're not filtering out enough possibilities to make that not the case.
The key will be to look at the results you're getting, and see what is actually different in the "duplicate" rows. I sometimes use a query like SELECT C.*, '--' as [--], CC.*, '--' as [--], ... to show all the columns of all the joined tables. (The as [--] would be as "--" in Postgres, `--` in MySQL.)

SQL: Count number of columns in all tables, excluding views

I am creating a query that returns the number of columns in each table, but I want to exclude Views.
The following works but returns View results:
SELECT COUNT(*), table_name
FROM INFORMATION_SCHEMA.COLUMNS
Group By table_name
Any suggestions?
NOTE: MSSQL 2005+
This assumes SQL 2005 or higher
SELECT
t.name,
count(c.name)
FROM
sys.tables t
inner join sys.columns c
ON t.object_id = c.object_id
group by t.name
Something like this:
SELECT COUNT(col.column_name), col.table_name
FROM information_schema.columns col
JOIN information_schema.tables tbl
ON tbl.table_name = col.table_name
AND tbl.table_schema = col.table_schema
AND tbl.table_catalog = col.table_catalog
AND tbl.table_type <> 'VIEW'
GROUP BY col.table_name
Join INFORMATION_SCHEMA.TABLES to find out if the table is a view.
SELECT COUNT(col.column_name), tab.table_name
FROM INFORMATION_SCHEMA.tables tab
JOIN INFORMATION_SCHEMA.COLUMNS col ON col.table_name = tab.table_name
WHERE tab.table_type != 'VIEW'
GROUP BY 2
ORDER BY 2
SELECT tab.table_name,COUNT(col.column_name)
FROM INFORMATION_SCHEMA.tables tab
JOIN INFORMATION_SCHEMA.COLUMNS col ON col.table_name = tab.table_name
WHERE tab.table_type != 'VIEW'
GROUP BY tab.table_name
ORDER BY tab.table_name
This code shows the table names and their columns count in front of them.
you can add the schema name if you want.