SQL query return Error "Function "has_column_privilege(oid,smallint,text)" not supported - sql

i have built Join query on redshift, but it doesn't work. Do you know why?
select
table_schema,
table_name,
sizeMB,
tbl_rows
from
(
select
table_schema ,
table_name
from information_schema.columns
where column_name = 'abcdef' -- enter table name here
and table_schema = 'prev'
and table_name not like '%crfg%'
group by table_schema, table_name
) as a(table_schema, table_name)
join
(
select "table" as tablename, size as sizeMB, tbl_rows
from svv_table_info
where "schema" = 'prev'
group by "table", size , tbl_rows
) as b(tablename, sizeMB,tbl_rows)
on a.table_name = b.tablename
and it got Error: "Function "has_column_privilege(oid,smallint,text)" not supported."

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

postgresql- select records based on field length inner join information_schema.columns

I have two tables:1. create table table_1(col1 text,col2 text) 2. create table table_2(tcol1 character varying(5), tcol2 character varying(5)).
table_1 has 50 records and table_2 is empty. I need to load those records from table_1 to table_2 if the length of table_2.tcol1 <= length of table_1.col1 and length of table_2.tcol2 <= length of table_1.col2.
I can do this like:
insert into table_2(tcol1,tcol2)
select col1,col2 from table_1
where char_length(col1) <=5 and char_length(col2) <=5
But in practical I have 100+ columns. Is there a way to achieve this by joining table_1 with information_schema.columns. The problem here is columns in table_1 are rows in information_schema.columns. Thanks for your interest in this question.
try this:
with tab2cols as (select table_schema, table_name, column_name, character_maximum_length, ordinal_position from information_schema.columns where table_name = 'table_2' and ordinal_position > 0),
tab1cols as (select table_schema, table_name, column_name, character_maximum_length, ordinal_position from information_schema.columns where table_name = 'table_1' and ordinal_position > 0),
tab1sel as (select 'select '||string_agg(column_name,',' order by ordinal_position)||' from '||table_schema||'.'||table_name as select_string from tab1cols group by table_schema, table_name),
tab2ins as (select 'insert into '||table_schema||'.'||table_name||' ('||string_agg(column_name,',' order by ordinal_position)||') 'as insert_string from tab2cols group by table_schema, table_name)
select string_agg(_text, ' ') from (
select insert_string as _text from tab2ins
union all
select select_string||' where ' as _text from tab1sel
union all
select string_agg('char_length('||t1.column_name||')<='||t2.character_maximum_length, ' AND ') as _text from tab2cols t2 join tab1cols t1 on t2.ordinal_position=t1.ordinal_position
) a
It will give you string like
"insert into myschema.table_2 (tcol1,tcol2) select col1,col2 from myschema.table_1 where char_length(col1)<=5 AND char_length(col2)<=5" which you can run in EXECUTE command or where ever you want.
I wrote it with CTE so all parts are clearly visible. Of course there are ways how to write it shorter etc... :-)

Oracle select index columns along with data type?

I am using the following SQL to grab index columns for a table:
SELECT DISTINCT COLUMN_NAME
FROM DBA_IND_COLUMNS
WHERE TABLE_NAME = 'MY_TABLE' AND TABLE_OWNER = 'SCHEMA'";
I want to adjust this SQL such that I grab the index columns and their data type:
SELECT DISTINCT COLUMN_NAME, DATA_TYPE
FROM DBA_IND_COLUMNS
WHERE TABLE_NAME = 'MY_TABLE' AND TABLE_OWNER = 'SCHEMA'";
But this gives an invalid identifier error for "DATA_TYPE". Is there a way to do this without creating another query?
You need to add DBA_TAB_COLUMNS to your query:
SELECT DISTINCT COL.COLUMN_NAME, COL.DATA_TYPE
FROM DBA_IND_COLUMNS IND
INNER JOIN DBA_TAB_COLUMNS COL
ON ( IND.TABLE_OWNER = COL.OWNER AND IND.TABLE_NAME = COL.TABLE_NAME AND IND.COLUMN_NAME = COL.COLUMN_NAME)
WHERE IND.TABLE_NAME = 'MY_TABLE' AND TABLE_OWNER = 'SCHEMA'