Find all tables without a certain column name - sql

So, I've seen lots of questions about finding all tables with a specific column name. However, I'm trying to find all tables WITHOUT a specific column. (In this case, EndDate). Is there a more elegant solution than just finding all the tables with that column, and comparing it to the list of all tables?

SELECT
table_name
FROM
INFORMATION_SCHEMA.TABLES T
WHERE
T.TABLE_CATALOG = 'MyDB' AND
T.TABLE_TYPE = 'BASE TABLE' AND
NOT EXISTS (
SELECT *
FROM INFORMATION_SCHEMA.COLUMNS C
WHERE
C.TABLE_CATALOG = T.TABLE_CATALOG AND
C.TABLE_SCHEMA = T.TABLE_SCHEMA AND
C.TABLE_NAME = T.TABLE_NAME AND
C.COLUMN_NAME = 'EndDate')

Try the following, It's standard SQL (and will work for almost every platform)
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES
EXCEPT
SELECT TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS
WHERE COLUMN_NAME = 'EndDate'
Just as you suggested, you can't really get anything that's simpler than this.

This should do it.
SELECT * FROM INFORMATION_SCHEMA.TABLES t
WHERE NOT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME = t.TABLE_NAME AND c.TABLE_SCHEMA=t.TABLE_SCHEMA
AND c.COLUMN_NAME='EndDate')

I have many more schemas and tables than I really ought to, so I need an optimized version that runs in a second.
Why not get all tables, then get all tables with the field, UNION ALL these results, and just show the table names where HAVING COUNT(table_name) = 1? That's just what I did.
Notice the two vars to change below: YourSchemaHere and YourFieldHere.
SELECT TABLE_NAME, COUNT(TABLE_NAME) FROM (
(SELECT DISTINCT c1.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS c1
WHERE c1.Table_Schema = "YourSchemaHere")
UNION ALL
(SELECT DISTINCT c2.TABLE_NAME
FROM INFORMATION_SCHEMA.COLUMNS c2
WHERE c2.Table_Schema = "YourSchemaHere" AND
c2.Column_Name = "YourFieldHere")
) x GROUP BY TABLE_NAME
HAVING COUNT(TABLE_NAME) = 1;
Online Demo at SQL Fiddle: http://sqlfiddle.com/#!9/791dde/1/0
Explanation of my approach:
Get all tables with : SELECT DISTINCT c1.TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS c1 WHERE c1.Table_Schema = "YourSchemaHere"
Get all tables with column : SELECT DISTINCT c2.TABLE_NAME FROM INFORMATION_SCHEMA.COLUMNS c2 WHERE c2.Table_Schema = "YourSchemaHere" AND c2.Column_Name = "YourFieldHere"
UNION ALL these two results.
Items in resulting list will be duplicated if they have the column, but only appear once if they do not.
Select only those without the field:HAVING COUNT(*) = 1

Related

Is there a function to return which phrase in array the row matched when using LIKE ANY (array['%term1%', '%term2%', etc.])?

I want all tables from my schema that match a list of other tables with similar names from a different schema. I am using the following query:
SELECT TABLE_NAME, COUNT(COLUMN_NAME) ColCount
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'schema_2' and TABLE_NAME LIKE ANY (array[
'%table1%',
'%table2%',
'%table3%',
'%table4%',
'%table5%'])
I want another column added to the output which specifies which name in the array the table from schema_2 matched, i.e.
TABLE_NAME COL_COUNT SCHEMA_1_TABLE
table1a 15 table1
Is there a way to do this?
You could try using a join. Kind of like:
WITH a AS (SELECT unnest(array['%table1%','%table2%','%table3%','%table4%','%table5%'])
AS table)
SELECT
isc.TABLE_NAME,
COUNT(isc.COLUMN_NAME),
REPLACE(a.table,'%','')
FROM
INFORMATION_SCHEMA.COLUMNS isc
LEFT JOIN a ON (isc.TABLE_NAME LIKE a.table)
WHERE
isc.TABLE_SCHEMA = 'schema_2'
AND a.table IS NOT NULL
GROUP BY
isc.TABLE_NAME,
a.table
You could also join INFORMATION_SCHEMA.COLUMNS with INFORMATION_SCHEMA.TABLES in order to just detect any duplication, not just the ones specified.

How to select the table with less columns in a database with Sql Server

I have a large database with a lot of tables and I want to know if I can select the table that have less columns of them. How can I do that? Is there some info in the INFORMATION_SCHEMA?
I feel like the other answers gave you plenty of info to help you answer your own questions with a little effort, but you don't seem satisfied, so maybe this helps.
If this isn't what you're looking for, you really need to edit your question so we can understand exactly what type of result you want.
This returns a single record for the table with the least number of columns. You can filter this down further by schema or whatever to fit your needs.
SELECT TOP 1
tbl.TABLE_CATALOG,
tbl.TABLE_SCHEMA,
tbl.TABLE_NAME,
COUNT(col.ordinal_position)
FROM INFORMATION_SCHEMA.TABLES tbl
JOIN INFORMATION_SCHEMA.COLUMNS col
ON tbl.TABLE_CATALOG = col.TABLE_CATALOG
AND tbl.TABLE_NAME = col.TABLE_NAME
AND tbl.TABLE_SCHEMA = col.TABLE_SCHEMA
WHERE tbl.table_type = 'BASE TABLE'
GROUP BY tbl.TABLE_CATALOG, tbl.TABLE_SCHEMA, tbl.TABLE_NAME
ORDER BY COUNT(col.ORDINAL_POSITION)
But what if there's a bunch of tables with only a single column? What to return? You can use TSQL and find the count of columns for the table with the least number of columns, and then select all tables with that count of columns.
BEGIN
DECLARE #minColumnCount INT
--This will find the count of columns for the table with the least number of columns
SELECT TOP 1 #minColumnCount = COUNT(col.ordinal_position)
FROM INFORMATION_SCHEMA.TABLES tbl
JOIN INFORMATION_SCHEMA.COLUMNS col
ON tbl.TABLE_CATALOG = col.TABLE_CATALOG
AND tbl.TABLE_NAME = col.TABLE_NAME
AND tbl.TABLE_SCHEMA = col.TABLE_SCHEMA
WHERE tbl.table_type = 'BASE TABLE'
GROUP BY tbl.TABLE_CATALOG, tbl.TABLE_SCHEMA, tbl.TABLE_NAME
ORDER BY COUNT(col.ORDINAL_POSITION)
--This will give you a list of tables that have exactly #minColumnCount columns
SELECT tbl.TABLE_CATALOG, tbl.TABLE_SCHEMA, tbl.TABLE_NAME, COUNT(col.ORDINAL_POSITION)
FROM INFORMATION_SCHEMA.TABLES tbl
JOIN INFORMATION_SCHEMA.COLUMNS col
ON tbl.TABLE_CATALOG = col.TABLE_CATALOG
AND tbl.TABLE_NAME = col.TABLE_NAME
AND tbl.TABLE_SCHEMA = col.TABLE_SCHEMA
WHERE tbl.table_type = 'BASE TABLE'
GROUP BY tbl.TABLE_CATALOG, tbl.TABLE_SCHEMA, tbl.TABLE_NAME
HAVING COUNT(col.ORDINAL_POSITION) = #minColumnCount
END
This will give you the list of tables and the count of columns for each table
SELECT TABLE_NAME,
COUNT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS col INNER JOIN
sys.objects obj
ON obj.name = col.TABLE_NAME
WHERE obj.type = N'U'
GROUP BY col.TABLE_NAME
List columns having a certain amount of columns:
SELECT TABLE_NAME, COUNT(*) AS NUMCOLS
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'YourTableName' AND TABLE_SCHEMA='YourSchemaName'
HAVING COUNT(NUMCOLS) > x
I think this is what you're looking for:
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = N'YourSchema'
AND TABLE_NAME = N'YourTable'
Detailed article: http://blog.sqlauthority.com/2012/07/20/sql-server-information_schema-columns-and-value-character-maximum-length-1/

DB2 SQL Show Long and Short Table Names?

I've started creating descriptive table names in DB2 and have found DB2 has a short name and a long name for each table.
EmployeePlan has a short name of Emplo00001
I would like to be able to display both names from a sql statement.
Here's my existing SQL -- is there a table I can join to in order to get the short name?
select * --table_name, system_column_name, column_text, Type_Name, column_Size, *
from sysibm.SQLColumns
where table_schem IN ('LAWMOD9T', 'LIBDDS')
and upper(table_name) IN ('EMPLOYEEPLAN')
ORDER BY system_column_name
And thank you, Darius X for answering my question so quickly. Here's my final query:
SELECT b.system_table_name as ShortName,
a.table_name, a.system_column_name, a.column_text,
a.type_name, a.column_size
FROM sysibm.SQLColumns a
INNER JOIN qsys2.systables b
ON a.table_name = b.table_name
AND a.table_schem = b.table_schema
WHERE UPPER(a.table_schem) IN ('LAWMOD9T', 'LIBDDS')
AND UPPER(a.table_name) IN ('EMPLOYEEPLAN')
ORDER BY a.table_schem, a.table_Name, a.ordinal_position
There may be more than one way, but if you run this query:
select *
from qsys2.systables
where table_schema IN ('LAWMOD9T', 'LIBDDS')
You'll see that SYSTEM_TABLE_NAME is one of the columns. So, you can join to qys2.systables using the schema and "long" table name.
You can add too the short name filter too
select
TABLE_NAME
from QSYS2.SYSTABLES
where table_schema = 'SchemaName' AND SYSTEM_TABLE_NAME = 'SystemName';

mysql get table column names in alphabetical order

Is it possible to query a MySQL database to get the column names of a table in alphabetical order? I know that
SHOW COLUMNS `table_name`;
or
DESCRIBE `table_name`;
will give me a list of the columns in a table (along with other info), but is it possible to alter the query in order to get the columns sorted alphabetically. Adding ORDER BY 'Field' didn't work, it gave a syntax error.
The ANSI INFORMATION_SCHEMA tables (in this case, INFORMATION_SCHEMA.COLUMNS) provide more flexibility in MySQL:
SELECT c.column_name
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.table_name = 'tbl_name'
-- AND c.table_schema = 'db_name'
ORDER BY c.column_name
Every field was listed twice until I used group by column name
select c.COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS c
where c.TABLE_NAME = `'tbl_name'`
group by c.column_name
order by c.column_name
If you want more details, below query is really handy:
SELECT COLUMN_NAME as 'Field',
COLUMN_TYPE as 'Type',
IS_NULLABLE as 'Null',
COLUMN_KEY as 'Key',
COLUMN_DEFAULT as 'Default',
EXTRA as 'Extra'
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME = 'my table' and
TABLE_SCHEMA = 'my database'
add ordering
order by Type; --

Search an Oracle database for tables with specific column names?

We have a large Oracle database with many tables. Is there a way I can query or search to find if there are any tables with certain column names?
IE show me all tables that have the columns: id, fname, lname, address
Detail I forgot to add: I need to be able to search through different schemas. The one I must use to connect doesn't own the tables I need to search through.
To find all tables with a particular column:
select owner, table_name from all_tab_columns where column_name = 'ID';
To find tables that have any or all of the 4 columns:
select owner, table_name, column_name
from all_tab_columns
where column_name in ('ID', 'FNAME', 'LNAME', 'ADDRESS');
To find tables that have all 4 columns (with none missing):
select owner, table_name
from all_tab_columns
where column_name in ('ID', 'FNAME', 'LNAME', 'ADDRESS')
group by owner, table_name
having count(*) = 4;
TO search a column name use the below query if you know the column name accurately:
select owner,table_name from all_tab_columns where upper(column_name) =upper('keyword');
TO search a column name if you dont know the accurate column use below:
select owner,table_name from all_tab_columns where upper(column_name) like upper('%keyword%');
The data you want is in the "cols" meta-data table:
SELECT * FROM COLS WHERE COLUMN_NAME = 'id'
This one will give you a list of tables that have all of the columns you want:
select distinct
C1.TABLE_NAME
from
cols c1
inner join
cols c2
on C1.TABLE_NAME = C2.TABLE_NAME
inner join
cols c3
on C2.TABLE_NAME = C3.TABLE_NAME
inner join
cols c4
on C3.TABLE_NAME = C4.TABLE_NAME
inner join
tab t
on T.TNAME = C1.TABLE_NAME
where T.TABTYPE = 'TABLE' --could be 'VIEW' if you wanted
and upper(C1.COLUMN_NAME) like upper('%id%')
and upper(C2.COLUMN_NAME) like upper('%fname%')
and upper(C3.COLUMN_NAME) like upper('%lname%')
and upper(C4.COLUMN_NAME) like upper('%address%')
To do this in a different schema, just specify the schema in front of the table, as in
SELECT * FROM SCHEMA1.COLS WHERE COLUMN_NAME LIKE '%ID%';
If you want to combine the searches of many schemas into one output result, then you could do this:
SELECT DISTINCT
'SCHEMA1' AS SCHEMA_NAME
,TABLE_NAME
FROM SCHEMA1.COLS
WHERE COLUMN_NAME LIKE '%ID%'
UNION
SELECT DISTINCT
'SCHEMA2' AS SCHEMA_NAME
,TABLE_NAME
FROM SCHEMA2.COLS
WHERE COLUMN_NAME LIKE '%ID%'
Here is one that we have saved off to findcol.sql so we can run it easily from within SQLPlus
set verify off
clear break
accept colnam prompt 'Enter Column Name (or part of): '
set wrap off
select distinct table_name,
column_name,
data_type || ' (' ||
decode(data_type,'LONG',null,'LONG RAW',null,
'BLOB',null,'CLOB',null,'NUMBER',
decode(data_precision,null,to_char(data_length),
data_precision||','||data_scale
), data_length
) || ')' data_type
from all_tab_columns
where column_name like ('%' || upper('&colnam') || '%');
set verify on