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

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.

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

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.

SQL column exist and not exist

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

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'