Oracle find all tables that have specific columns - sql

I want to find all tables in my database that have two columns LOCATION and ASSET_ID
So I tried this :
select owner, table_name, column_name
from all_tab_columns
where column_name in ('LOCATION','ASSET_ID');
the problem is this query give all tables that have LOCATION or ASSET_ID not both of them.
so I changed it to this :
select owner, table_name, column_name
from all_tab_columns
where 1=1
and column_name ='LOCATION'
and column_name = 'ASSET_ID';
it shows 0 result.
Please help.

Select all the rows as in your initial attempt. Then group by owner and table_name and keep only those that have TWO rows returned in the initial query. Use the having clause for that:
select owner, table_name
from all_tab_columns
where column_name in ('LOCATION','ASSET_ID')
group by owner, table_name
having count(*) = 2
;

You can do this using a couple of subqueries factored as common table expressions and a join, as in:
WITH cteLOCATION AS (SELECT OWNER, TABLE_NAME
FROM ALL_TAB_COLS
WHERE COLUMN_NAME = 'LOCATION'),
cteASSET_ID AS (SELECT OWNER, TABLE_NAME
FROM ALL_TAB_COLS
WHERE COLUMN_NAME = 'ASSET_ID')
SELECT OWNER, TABLE_NAME
FROM cteLOCATION
NATURAL JOIN cteASSET_ID
This is one of the very few situations where I'd ever use NATURAL JOIN.
SQLFiddle here
Best of luck.

Using joins (similar to #BobJarvis' https://stackoverflow.com/a/47984132/754550 but more traditional without with - clause):
select a1.owner,a1.table_name
from all_tab_columns a1,
all_tab_columns a2
where a1.owner=a2.owner
and a1.table_name=a2.table_name
and a1.column_name='LOCATION'
and a2.column_name='ASSET_ID'
order by a1.owner,a1.table_name
or using sets:
select owner, table_name
from all_tab_columns
where column_name='LOCATION'
intersect
select owner, table_name
from all_tab_columns
where column_name='ASSET_ID'
order by owner, table_name
or using 'group by' clause as already posted here https://stackoverflow.com/a/47981174/754550 by #mathguy
select owner, table_name
from all_tab_columns
where column_name in ('LOCATION', 'ASSET_ID')
group by owner, table_name
having count(*)=2
order by owner, table_name

try this,
SELECT *
FROM (SELECT a.*,
COUNT(1) OVER (PARTITION BY table_name) cnt
FROM all_tab_columns a
WHERE column_name IN ('LOCATION','ASSET_ID')
ORDER BY table_name)
WHERE cnt = 2

Related

Oracle Column table Count - Sub-Selection

I really only want the number of columns in the tables in the SQL query, but somehow i can't get the right result. Does anybody know what I'm doing wrong?
select count(*) from user_tab_columns where table_name='tablename' //works and gives me the number of columns
select
TABLE_NAME,
NUM_ROWS,
(select count(*) from user_tab_columns where table_name=TABLE_NAME) as Test
from user_tables
Haha, look at this:
where table_name=TABLE_NAME
This will always be true, because the table name is the table name.
Here is the query with qualified column names:
select
table_name,
num_rows,
(select count(*) from user_tab_columns tc where tc.table_name = t.table_name) as test
from user_tables t;
As an alternative, you could aggregate the whole query:
select t.table_name
, num_rows
, count(*) as num_columns
from user_tables t
join user_tab_columns c on c.table_name = t.table_name
group by t.table_name, t.num_rows
order by 1;

Select Tables that do not contain a certain column in Oracle 12c

Most of the tables in the DB have a certain column 'col_abc'.
How can I find the tables that do not contain this column 'col_abc'.
The query
select table_name
from user_tab_columns
where column_name not in ('COL_ABC')
does not return expected result.
Thanks,
Amit
Here is one way:
select table_name from user_tables
minus
select table_name from user_tab_columns
where column_name = 'ABC';
The Below Query will give the expected results. Please modify <ur_Schema_name> as the required schema name
SELECT * FROM ALL_TABLES at
WHERE at.OWNER = <ur_Schema_name>
AND NOT EXISTS (SELECT 1 FROM ALL_TAB_COLUMNS atc
WHERE atc.TABLE_NAME = at.TABLE_NAME
AND atc.OWNER =at.OWNER
AND atc.COLUMN_NAME='COL_ABC'
AND atc.OWNER=<ur_Schema_name>);
If you only need to look in the current user's schema, this is probably the simplest way to write the query:
select table_name
from user_tables
where table_name not in (
select table_name
from user_tab_columns
where column_name = 'COL_ABC'
)
;
This uses in a crucial way the fact that the column table_name in user_tab_columns is constrained not null.
If you need to look across all schemas, you need to use the dba_ or all_ dictionary views, and look for (owner, table_name) pairs instead of just table_name. Left as further exercise for you.
You could also use this solution using LEFT JOIN. It is a kind of NOT EXISTS clause.
select t.*
from user_tables t
left join (
select table_name
from user_tab_columns
where column_name = 'COL_ABC'
) tc
on (t.table_name = tc.table_name)
where tc.table_name is null
;

getting number of columns and rows in my tables

How to get the number of columns and rows for each of my tables in oracle?
So far I know how to display the number of columns for each table:
select table_name, count(*)
from all_tab_columns
where owner = 'user'
group by table_name
SELECT T.owner,
t.table_name,
t.num_rows, --it depends analyze (gather statics etc.) we can't depend it.
To_number(Extractvalue(Xmltype(
dbms_xmlgen.Getxml('select count(*) c from '
||table_name)),
'/ROWSET/ROW/C')) real_count,
(SELECT Count(*)
FROM all_tab_columns C
WHERE C.table_name = T.table_name) COLUMN_COUNT
FROM all_tables t
WHERE OWNER='user' --and T.table_name = 'MYTABLE'
GROUP BY t.owner,
t.table_name,
t.num_rows

How to also select row count from following query? - Oracle SQL

Need to also select the row/record count using the following query in Oracle SQL. How would I go about doing this?
SELECT DISTINCT t.OWNER AS TABLE_SCHEMA, t.Table_Name, c.COLUMN_NAME, c.DATA_TYPE,
(
SELECT CASE WHEN cons.CONSTRAINT_TYPE = 'P' THEN 'Primary Key' ELSE NULL END
FROM SYS.all_cons_columns cols
INNER JOIN SYS.all_constraints cons ON cons.constraint_name=cols.constraint_name AND cons.constraint_type = 'P'
WHERE cols.Column_name=c.column_name AND cols.TABLE_NAME=c.TABLE_NAME AND cols.OWNER=c.OWNER
) AS CONSTRAINT_TYPE, c.DATA_PRECISION, c.DATA_SCALE
FROM SYS.ALL_TABLES t
INNER JOIN SYS.all_tab_columns c ON c.TABLE_NAME=t.TABLE_NAME AND c.OWNER=t.OWNER
WHERE t.OWNER = 'MY_SCHEMA_NAME' AND t.Table_Name = 'MY_TABLE_NAME'
If you can live with an estimate number of rows (whose accuracy depends on the freshness of each table's statistics), you can just use column NUM_ROWS from ALL_TABLES:
SELECT
t.OWNER AS TABLE_SCHEMA,
t.Table_Name,
c.COLUMN_NAME,
c.DATA_TYPE,
t.NUM_ROWS, --> here
...
FROM all_tables t
INNER JOIN all_tab_columns c ...
Note that DISTINCT seem superfluous here - your query generates one record per column in the table.
If you really need the exact count, then you can use an inline query - but you need to hardcode the table name:
SELECT
t.OWNER AS TABLE_SCHEMA,
t.Table_Name,
c.COLUMN_NAME,
c.DATA_TYPE,
(SELECT COUNT(*) FROM my_schema_name.my_table_name) no_rows,
...
FROM all_tables t
INNER JOIN all_tab_columns c ...
WHERE t.OWNER = 'MY_SCHEMA_NAME' AND t.Table_Name = 'MY_TABLE_NAME'
Not sure which SQL you are using but you might put the whole result into a temp table
like
INTO temp temp_table_count WITH NO LOG;
SELECT COUNT(*) FROM temp_table_count;
https://www.oracletutorial.com/oracle-basics/oracle-private-temporary-table/ the reference
INSERT INTO ora$ppt_temp_table_count(ADD ALL COLUMNS HERE
COMMASEPARATED)
SELECT col1, col2, col3
FROM source_table
WHERE condition; <-- your query
SELECT COUNT(*) FROM ora$ppt_temp_table_count;

SQL Query in sap hana

I have a database and have 2 schema called DWFR and DWFR3 , what i need to do is compare 2 schmea and take the matching table name and also the table present in DWFR schema which is not available on DWFR3 and also with the below condition
SELECT schema_name, table_name
FROM tables
WHERE schema_name = 'DWFR'
AND table_name NOT LIKE 'RA%'
AND table_name NOT LIKE 'ZZ%'
AND table_name NOT LIKE 'DELETE%'
AND table_name NOT LIKE '%TEST%'
AND table_name NOT LIKE 'XX%'
AND table_name NOT LIKE 'ROB%'
AND table_name IN (
SELECT table_name
FROM tables
WHERE schema_name = 'DWFR3'
AND table_name NOT LIKE 'RA%'
AND table_name NOT LIKE 'ZZ%'
AND table_name NOT LIKE 'DELETE%'
AND table_name NOT LIKE '%TEST%'
AND table_name NOT LIKE 'XX%'
AND table_name NOT LIKE 'ROB%'
)
ORDER BY schema_name, table_name;
This will get the matched table names but i also want table name available in DWFR which is not their on DWFR3.
You can use a LEFT OUTER JOIN for selecting all data rows from a set and matchings from a second set.
I used a SQL CTE Common Table Expression in the script, you can think of it as a sub-select with additional uses
Here is how you can use for your case
with t2 as (
select table_name
from tables
where schema_name = 'DWFR3'
)
select t1.table_name, t2.table_name
from tables t1
left outer join t2
on t1.table_name = t2.table_name
where t1.schema_name = 'DWFR'
And you also need the append the additional requirements or WHERE clauses into above script
For the reason that I used CTE can be explained as follows.
In fact, the actual solution should be as simple as following.
Unfortunately, HANA seems to not supporting additional filtering criteria with ON clause on JOINs
select t1.table_name, t2.table_name
from tables t1
left outer join tables t2
on t1.table_name = t2.table_name and t2.schema_name = 'DWFR3
where t1.schema_name = 'DWFR'
Because of this reason, I had to filter the LEFT part of the JOIN earlier than applying the ON, join condition
To find matched table names in both schemas:
select
'DWFR' as schema_name,
table_name
from
(
select table_name from tables where schema_name = 'DWFR'
intersect
select table_name from tables where schema_name = 'DWFR3'
) x
where
table_name not like 'RA%' and
table_name not like 'ZZ%' and
table_name not like 'DELETE%' and
table_name not like '%TEST%' and
table_name not like 'XX%' and
table_name not like 'ROB%';
To find table names in DWFR but not in DWFR3:
select
'DWFR' as schema_name,
table_name
from
(
select table_name from tables where schema_name = 'DWFR'
except
select table_name from tables where schema_name = 'DWFR3'
) x
where
table_name not like 'RA%' and
table_name not like 'ZZ%' and
table_name not like 'DELETE%' and
table_name not like '%TEST%' and
table_name not like 'XX%' and
table_name not like 'ROB%';