How to find column name that contains specific string value using oracle - sql

How to find column name contains particular string value in my table sku_config using oracle.
for example my string is TRP , I need to find the column name that is having value 'TRP' in mytable.
here column name can be any column belongs to my table.
Here is psudo code for my requirement.
select column_name from sku_config where contains 'TRP'.

You can use xmlquery as follows:
SELECT column_name FROM
(select column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(1) as c '
|| 'from ' || table_name || ' WHERE ' || column_name || ' LIKE ''%TRP%'''))
returning content)) as c
from all_tab_columns
where TABLE_NAME = 'SKU_CONFIG')
WHERE C > 0;
Example:
Current data of sample table:
SQL> SELECT * FROM ABC;
NAME DE
--------------- --
TEJASH2 SO
TEJASH3 DO
ABC SO
XXXXXXXXX SO
A A
B B
TEJASH1 SO
7 rows selected.
Searching for TEJASH string
SQL> SELECT column_name FROM
2 (select column_name,
3 to_number(xmlquery('/ROWSET/ROW/C/text()'
4 passing xmltype(dbms_xmlgen.getxml(
5 'select count(1) as c '
6 || 'from ' || table_name || ' WHERE ' || column_name || ' LIKE ''%TEJASH%'''))
7 returning content)) as c
8 from all_tab_columns
9 where TABLE_NAME = 'ABC')
10 WHERE C > 0;
COLUMN_NAME
-------------
NAME
Searching for SO string
SQL>
SQL>
SQL> SELECT column_name FROM
2 (select column_name,
3 to_number(xmlquery('/ROWSET/ROW/C/text()'
4 passing xmltype(dbms_xmlgen.getxml(
5 'select count(1) as c '
6 || 'from ' || table_name || ' WHERE ' || column_name || ' LIKE ''%SO%'''))
7 returning content)) as c
8 from all_tab_columns
9 where TABLE_NAME = 'ABC')
10 WHERE C > 0;
COLUMN_NAME
------------
DEPT
SQL>

If you want to find the names of the columns in a table that look like something, then use user_tab_columns:
select column_name
from user_tab_columns
where table_name = 'sku_config' and
column_name like '%TRP%';

you can use the following code to find a column with a specific string.
select COLUMN_NAME
from TABLE_NAME
where COLUMN_NAME="STRING"
group by COLUMN_NAME

Related

How to find the number of columns in which records are more than 3?

To solve this problem I take names of columns from information_schema.columns and make query which should count number of records in one column. But that subquery returns more than 1 value and I don't know why, because it should return number of rows - one value. Please explain me what I'm doing wrong.
SELECT count(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'users' group by COLUMN_NAME having((select count(COLUMN_NAME) from users where COLUMN_NAME is not null)>3)
Columns
name | surname
__________________
a | b
c | d
e | f
e | null
Function should return 1 (name column have 4 records)
You can try this solution:
DECLARE dsql STRING;
DECLARE qry STRING;
SET qry = (
SELECT
STRING_AGG(ARRAY_TO_STRING(["SELECT '", column_name, "' AS ColumnName, " || "COUNT(" || column_name || ") AS RowCount FROM mydataset.", table_name, ' union all'], ''), ' ')
FROM
mydataset.INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'users' );
SET dsql = 'SELECT * FROM ( ' || SUBSTR(qry, 1, LENGTH(qry) - LENGTH(' union all')) || ') WHERE RowCount > 3';
EXECUTE IMMEDIATE dsql;

How to find all the tables having column with CHAR Datatype and having numeric value in it?

I want to find all the tables which have columns with char data type but have numeric entry in it ,for instance if there is some table X with column VALID_FLAG CHAR(1) , then I have to check if this column has value 0 or 1 in it ?
I have no clue of this ,Please guide .
You can not achieve this using single query. You can write the PL/SQL procedure in oracle which will do the following:
Get the list of tables with columns where datatype is CHAR:
select table_name,COLUMN_NAME,DATA_TYPE from ALL_TAB_COLUMNS where data_type='CHAR'
and OWNER='OWNER_NAME';
Then you can put the check for 1 or 0:
select count(*) from table_name where column_name in ('1','0');
You can take advantage of xmlquery and find the desired output in a single query as following:
WITH DATAA AS(select /*+ MATERIALIZE */ owner, table_name, column_name,
to_number(xmlquery('/ROWSET/ROW/C/text()'
passing xmltype(dbms_xmlgen.getxml(
'select count(1) as c '
|| 'from ' || table_name || ' WHERE ' || COLUMN_NAME || ' IN (''0'',''1'')'))
returning content)) as c
from user_tab_columns
WHERE
DATA_TYPE = 'CHAR')
SELECT * FROM DATAA
WHERE C > 0;
Cheers!!

How can i get a count(*) of all the columns in a table? Using PostgreSql

I have bunch of tables where several of them have hundreds of columns. I need to get a count of non-null values for each column and I've been doing it manually. I would like to figure out a way to get all the counts for all the columns in a table. I looked up stackoverflow and google, but unable to find the answer.
I tried this but it's just returning a value of 1 for each column. I know it's just counting the number of column and not the values in each column. Any suggestions?
select count(COLUMN_NAME)
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
group by COLUMN_NAME
COUNT(column_name) always gives you the count of NON NULL values.
Create a generic function like this which can take schema name and table name as arguments.
Here I am constructing select statements joined together by UNION ALLs each returning the value of the column_name and it's count for all columns when executed dynamically.
CREATE OR REPLACE FUNCTION public.get_count( TEXT, TEXT )
RETURNS TABLE(t_column_name TEXT, t_count BIGINT )
LANGUAGE plpgsql
AS $BODY$
DECLARE
p_schema TEXT := $1;
p_tabname TEXT := $2;
v_sql_statement TEXT;
BEGIN
SELECT STRING_AGG( 'SELECT '''
|| column_name
|| ''','
|| ' count('
|| column_name
|| ') FROM '
|| table_schema
|| '.'
|| table_name
,' UNION ALL ' ) INTO v_sql_statement
FROM information_schema.columns
WHERE table_schema = p_schema
AND table_name = p_tabname;
IF v_sql_statement IS NOT NULL THEN
RETURN QUERY EXECUTE v_sql_statement;
END IF;
END
$BODY$;
Execution
knayak=# select c.col, c.count from
public.get_count( 'public', 'employees' ) as c(col,count);
col | count
----------------+-------
employee_id | 107
first_name | 107
last_name | 107
email | 107
phone_number | 107
hire_date | 107
job_id | 107
salary | 107
commission_pct | 35
manager_id | 106
department_id | 106
(11 rows)
There's not really a magic way to do this. If you need to check each of 100 different columns to see how many non-null values there are, you'll have to specify each of the columns of the table.
About the best you can do is use the system catalogs to help write your queries:
select 'SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name'
and is_nullable = 'YES'
You may need to add quoted identifiers if you've got spaces or other special characters in your column names.
Then you can copy that output to another query and add the missing parts of the query. I've added and is_nullable = 'YES' because it's a waste of time to check NOT NULL columns. As far as I know, that column is present in PostgreSQL.
Try this
SELECT
sum(case when column1 is not null then 1 else 0 end) as col1_not_null_count
sum(case when column2 is not null then 1 else 0 end) as col2_not_null_count
sum(case when column3 is not null then 1 else 0 end) as col3_not_null_count
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
The best way I've found to do this is to write a case statement to make a non-null value in a column become a 1 and a null become a 0. Then I sum the case to get a count of the non-null values:
SELECT SUM(CASE WHEN COLUMN_NAME1 IS NULL THEN 1 ELSE 0 END) AS COL1_COUNT
, SUM(CASE WHEN COLUMN_NAME2 IS NULL THEN 1 ELSE 0 END) AS COL2_COUNT
FROM TABLE_NAME
I see in your select that you are looking at the information_schema.columns table. You can dynamically generate the code above by a select from that table:
SELECT ', SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT'
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
You can also dynamically create a different select for every column in the table in question:
SELECT 'SELECT SUM(CASE WHEN ' + column_name + ' IS NULL THEN 1 ELSE 0 END) AS ' + column_name + '_COUNT FROM ' + table_schema + '.' + table_name
FROM information_schema.columns
WHERE table_schema = 'schema_name'
AND table_name = 'table_name'
I came here looking to answer the same question, but I wanted to do this without making a function, as I don't always have the ability to do that in the databases I'm working with. But the databases I work with have the tblfunc module installed, which has the crosstab function, that takes an sql string as input. I was able to produce sql that I could use in that function to get all the column counts from any table. Here is the code I used, where I put in the schema_name and table_name of what I wanted:
select * from crosstab('select column_name, ''num'' as category, sum(num) from (' || (
select
string_agg(sql, '') as sql_string
from (
select
case when row_number() OVER () = 1 then '' else ' union all ' end ||
'select ''' || column_name || ''' as column_name, ' || 'count(' || column_name || ') as num from ' || table_schema || '.' || table_name as sql
from information_schema.columns
where table_schema = 'schema_name'
and table_name = 'table_name') as sql_query limit 1
) || ') as column_counts group by column_name, category')
AS t(column_name text, num numeric) order by num asc

plsql List all table.column containing null values

I'd like to find all column of a set of table with null values in them.
I can find the table and column names
SELECT TABLE_NAME, COLUMN_NAME
FROM user_tab_cols
where nullable='Y'
and table_name in ('myTalbe', 'myTable2');
And also check if the are nulls
select count(*) from myTable where myColumn is null;
but how can I put this toghether to have as result
table_name column_name
myTable myColumn
myTable myCol2
myTable2 col4
An approach could be with some dynamic SQL, but this would require some PL/SQL code; the following only uses SQL to get the result you need:
select *
from (
select table_name,
column_name,
to_number(extractvalue(xmltype(dbms_xmlgen.getxml('select count(*) c from '||table_name || ' where ' || column_name || ' is null')),'/ROWSET/ROW/C')) as rowcount
from user_tab_columns
where nullable='Y'
and table_name in ('myTalbe', 'myTable2')
)
where rowcount > 0
This could be an approach with dynamic SQL:
declare
type tableOfNumber is table of number;
type tableOfChar is table of varchar2(30);
--
vSQl varchar2(4000);
vListNumbers tableOfNumber;
vListTables tableOfChar;
vListColumns tableOfChar;
begin
select listagg( 'select ''' ||
table_name || ''' as table_name, ''' ||
column_name || ''' as column_name, count(*) as rowCount from ' ||
table_name ||
' where ' ||
column_name ||
' is null having count(*) > 0' ,
' UNION ALL '
) within group ( order by table_name, column_name)
into vSQL
from user_tab_columns
where nullable='Y'
and table_name in ('myTalbe', 'myTable2');
--
dbms_output.put_line(vSQL);
/* whatever you may want to do with the query */
/* for example, fetch into some variables and print the result */
execute immediate vSQL
bulk collect into vListTables, vListColumns, vListNumbers;
--
if vListTables.count() > 0 then
for i in vListTables.first .. vListTables.last loop
dbms_output.put_line('Table ' || vListTables(i) ||
', column ' || vListColumns(i) ||
', number of nulls: ' || vListNumbers(i)
);
end loop;
end if;
end;
Here's a routine I wrote a while back to do exactly that. It will output the required DDL to make those columns that are nullable (but do not contain any nulls) not nullable.
https://connormcdonald.wordpress.com/2016/03/11/tightening-up-your-data-model/
It can do the task for a schema or a single table.

Retrieval of Column name in Oracle

how to retrieve a column name based on the value given in i wnat to get the column_name in oracle
like i dont know a cloumn name but i know the column value
i have tried in this way
select column_name from table_name where column_value=XXXXX;
Try like this:
SQL> select table_name,
column_name,
:search_string search_string,
result
from cols,
xmltable(('ora:view("'||table_name||'")/ROW/'||column_name||'[ora:contains(text(),"%'|| :search_string || '%") > 0]')
columns result varchar2(10) path '.'
)
where table_name in ('EMP', 'DEPT')
Source
If you want to do it in plain SQL, then you could use the XML approach.
For example, to search for the value KING in SCOTT schema:
SQL> variable val varchar2(10)
SQL> exec :val := 'KING'
PL/SQL procedure successfully completed.
SQL> SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
2 SUBSTR (table_name, 1, 14) "Table",
3 SUBSTR (column_name, 1, 14) "Column"
4 FROM cols,
5 TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
6 || column_name
7 || ' from '
8 || table_name
9 || ' where upper('
10 || column_name
11 || ') like upper(''%'
12 || :val
13 || '%'')' ).extract ('ROWSET/ROW/*') ) ) t
14 ORDER BY "Table"
15 /
Searchword Table Column
----------- -------------- --------------
KING EMP ENAME
SQL>
Read SQL to Search for a VALUE in all COLUMNS of all TABLES in an entire SCHEMA