Compare two tables and return colum names which are not equal in two tables - sql

I have two Tables which are, TS_SALES and TS_SALES_AUDIT.
Here TS_SALES is parent table and TS_SALES_AUDIT is child table.
when i count the columns in two tables using below code,
1) SELECT count(*) FROM user_tab_columns WHERE table_name = 'TS_SALES';
---------
Count(*)
---------
130
2) SELECT count(*) FROM user_tab_columns WHERE table_name = 'TS_SALES_AUDIT';
---------
Count(*)
---------
40
Can we return the column names which are not equal in both tables?

This should do the trick:
Columns that are in TS_SALES but not in TS_SALES_AUDIT
SELECT column_name FROM user_tab_columns WHERE table_name = 'TS_SALES'
minus
SELECT column_name FROM user_tab_columns WHERE table_name = 'TS_SALES_AUDIT'
Columns that are in TS_SALES_AUDIT but not in TS_SALES
SELECT column_name FROM user_tab_columns WHERE table_name = 'TS_SALES_AUDIT'
minus
SELECT column_name FROM user_tab_columns WHERE table_name = 'TS_SALES'

One method uses aggregation:
select max(table_name) as which_table_name,
max(column_name) as which_column_name
from user_tab_columns
where table_name in ('TS_SALES', 'TS_SALES_AUDIT')
group by column_name
having count(*) = 1;

To get the columns that exist in TS_SALES and not in TS_SALES_AUDIT, you can use the following query:
SELECT COLUMN_NAME FROM user_tab_columns
WHERE table_name = 'TS_SALES'
AND COLUMN_NAME NOT IN
(
SELECT COLUMN_NAME FROM user_tab_columns WHERE table_name = 'TS_SALES_AUDIT'
)
To achieve the reverse, use the following:
SELECT COLUMN_NAME FROM user_tab_columns
WHERE table_name = 'TS_SALES_AUDIT'
AND COLUMN_NAME NOT IN
(
SELECT COLUMN_NAME FROM user_tab_columns WHERE table_name = 'TS_SALES'
)

Related

Select data for columns that are only in another table

I have two tables, table1 and table2, that have columns common to both.
The queries that obtain the column names of each table are given below,
Query to get columns from first table:
select column_name from information_schema.columns
where table_schema = 'schema1'
and table_name = 'table1';
Query to get columns from second table:
select column_name from information_schema.columns
where table_schema = 'schema2'
and table_name = 'table2';
I need to select data from table2, only the columns which are also in table1.
I do not have a postrgesql intace at the moment but Dynamic SQL is what you need.
The following query will get you the column names that appear in both table 1 and table 2.
select string_agg(column_name, ',') FROM (
select column_name from information_schema.columns
where table_schema = 'schema1'
and table_name = 'table1'
intersect
select column_name from information_schema.columns
where table_schema = 'schema2'
and table_name = 'table2'
)
And you need to build
EXECUTE 'select ' || select string_agg(column_name, ',') FROM (
select column_name from information_schema.columns
where table_schema = 'schema1'
and table_name = 'table1'
intersect
select column_name from information_schema.columns
where table_schema = 'schema2'
and table_name = 'table2'
) || ' from schema2.table2 '
Sory if there any syntax error as writing from mobile app, you can join both result set to get common data.
select column_name from information_schema.columns T2
JOIN (select column_name from information_schema.columns where table_schema = 'schema1' and table_name = 'table1') T1
ON T2.COLUMN_NAME = T1.COLUMN_NAME Where T2.table_schema = 'schema2' and T2.table_name = 'table2';

Compare Tables column_name with views column_names

Aim is to compare tables column_name with the views columns_name to check if they have the same columns , however, getting them with different orders. Wanted to see them both with same order
select t1.COLUMN_NAME, t2.COLUMN_NAME from
(select * from information_schema.columns where TABLE_SCHEMA = 'dmt' and table_name = '#tablename' ) as t1
left join
(select * from information_schema.columns where TABLE_SCHEMA = 'models' and table_name = 'viewName') as t2
on t1.ORDINAL_POSITION = t2.ORDINAL_POSITION
I want get the output like in the same order, for example:
Column_Name 1 Column_Name 2
cat cat
dog dog
You can use the following to get the comparison of the columns.
WITH ColumnsCTE (TABLE_NAME, COLUMN_NAME) AS
(
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'dmt' AND TABLE_NAME = 'TableName'
UNION ALL
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'models' AND TABLE_NAME = 'ViewName'
)
-- get the different columns of the tables / views.
SELECT t1.TABLE_NAME, t1.COLUMN_NAME AS [COLUMN_NAME 1], ISNULL(t2.COLUMN_NAME, 'missing on other table / view') AS [COLUMN_NAME 2]
FROM ColumnsCTE AS t1 LEFT JOIN ColumnsCTE AS t2 ON t1.COLUMN_NAME = t2.COLUMN_NAME AND t1.TABLE_NAME <> t2.TABLE_NAME
WHERE t2.COLUMN_NAME IS NULL
demo on dbfiddle.uk
You can't use the ORDINAL_POSITION to get the expected result since the order of the columns can be different. See the following example where the ORDINAL_POSITION is different but the columns are available in both tables / views:
CREATE TABLE Test (
id INT,
name VARCHAR(100)
);
CREATE VIEW ViewTest AS
SELECT name, id FROM Test;
If the order of the attributes is identitcal (you can hardcode which attributes to select and in which order)
i strongly recommend
"intersect" or "except" command
increddibly strong function offering almost anything you could wish for here.

SQL: counting columns that can have null values

so I have a query that retrieves names of tables and count of columns in each of them.
SELECT Table_Schema, Table_Name, COUNT(*)
FROM Information_Schema.Columns
GROUP BY Table_Schema, Table_Name
HAVING Table_Schema = 'schema';
How can I add to this query count of columns that CAN store NULL values?
You can add a FILTER condition to the aggregate function to only count the rows where the condition is met:
SELECT table_Schema,
table_Name,
count(*) AS total_columns,
count(*) FILTER (WHERE is_nullable = 'YES') AS nullable_columns
FROM information_schema.columns
GROUP BY table_Schema, table_Name
HAVING table_schema = 'schema';
Use the is_nullable column:
SELECT Table_Schema, Table_Name, COUNT(*)
FROM Information_Schema.Columns
WHERE is_nullable = 'YES'
GROUP BY Table_Schema, Table_Name
HAVING Table_Schema = 'schema';
The documentation on information_schema.columns describes the table in full detail, including other columns that might be of interest.
EDIT:
If you want to add the information to the existing query, just use conditional aggregation:
SELECT Table_Schema, Table_Name, COUNT(*), SUM( (is_nullable = 'YES')::int ) as nullable_clumns
FROM Information_Schema.Columns
GROUP BY Table_Schema, Table_Name
HAVING Table_Schema = 'schema';

Selecting column names separated by a comma

I want to write a SQL statement (SQL Server) which selects column names under specific conditions and "returns" all column names separated by a ,.
SELECT COLUMN_NAME
FROM all_tab_columns
WHERE OWNER = 'KOCH' AND TABLE_NAME = 'TABLE1';
This returns several rows of column names:
NAME
ID
STATE
CITY
But I want them to be returned in this format:
NAME, ID, STATE, CITY
(I think I have to use FROM dual)?
For Oracle:
;WITH CTE_Columns (column_list, column_id) AS
(
SELECT
CAST(COLUMN_NAME AS VARCHAR(500)) AS column_list,
COLUMN_ID
FROM USER_TAB_COLUMNS C
WHERE
TABLE_NAME = 'TABLE1' AND
COLUMN_ID= 1
UNION ALL
SELECT
CAST(column_list + ', ' + C.COLUMN_NAME AS VARCHAR(500)),
C.COLUMN_ID
FROM
CTE_Columns CL
INNER JOIN USER_TAB_COLUMNS C ON
C.TABLE_NAME = 'TABLE1' AND
C.COLUMN_ID = CL.COLUMN_ID + 1
)
SELECT column_list
FROM CTE_Columns
WHERE
COLUMN_ID =
(
SELECT MAX(COLUMN_ID)
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = 'TABLE1')

How do I list all tables in a schema having specific column in oracle sql?

I have found the list of all tables using this query -
SELECT DISTINCT OBJECT_NAME
FROM USER_OBJECTS
WHERE OBJECT_TYPE = 'TABLE'
But I need to list all the tables having column name starttime_date or starttime.
You could use USER_TAB_COLS view.
For example,
SQL> select table_name, column_name, data_type from user_tab_cols where column_name ='DEPTNO';
TABLE_NAME COLUMN_NAM DATA_TYPE
---------- ---------- ----------
DEPT DEPTNO NUMBER
EMP DEPTNO NUMBER
SQL>
You could try,
select *
from user_tab_cols
where column_name in ('STARTTIME_DATE', 'STARTTIME');
At first, you connect any schema then you could try to this SQL.
For example:
SELECT TABLE_NAME,
COLUMN_NAME,
DATA_TYPE,
DATA_LENGTH,
NULLABLE
FROM all_tab_columns
WHERE OWNER = 'schema_name' and column_name = 'column_name';