Query:
SELECT string_agg(column_name::text, ',')
FROM information_schema.columns
WHERE table_name = 'my_table' and column_name !='id'
returns list of columns in my_table except 'id':
date_of_birth,first_name,last_name,e_mail
I would like to use this list in INSERT INTO statement when defining columns names. How should I do it, because following don't work.
INSERT INTO my_table2 (
SELECT string_agg(column_name::text, ',')
FROM information_schema.columns
WHERE table_name = 'my_table' and column_name !='id'
)
VALUES ('a', 'b', ...);
I have changing column count and order in my_table2 and my_table so I must assign names automatically .
You have to use dynamic SQL, that is, construct a second query from the result of the first one. There is no way to do it in a single statement.
With psql's \gexec, you could use
SELECT format($$INSERT INTO my_table2 (%s) VALUES ('a', 'b', ...)$$,
string_agg(quote_ident(column_name), ', ')
)
FROM information_schema.columns
WHERE table_name = 'my_table'
AND column_name <> 'id' \gexec
Related
This SQL returns a comma-separated list of column names for the table 'MyTable'
DECLARE #colnames VARCHAR(max);
SELECT
#colnames = COALESCE(#colnames + ',', '') + column_name
FROM
CORP_MLR_Rebates.INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'MyTable';
SELECT #colnames;
Why doesn't the following give me a tab-separated list the same columns? Instead, it is space-separated.
DECLARE #colnames VARCHAR(max);
SELECT
#colnames = COALESCE(#colnames + char(9), '') + column_name
FROM
CORP_MLR_Rebates.INFORMATION_SCHEMA.COLUMNS
WHERE
table_name = 'MyTable';
SELECT #colnames;
In my testing it does work, I guess it just depends on how you retrieve the results (I have to output the result to a file to get the correct results)
You will likely get spaces using the SSMS GUI. Returning the results as text or to a file will give you tabs; e.g. CHAR(9). Consider these three queries that all do the job:
;--== 1. Updatable Variable
DECLARE #colnames VARCHAR(max);
SELECT #colnames = COALESCE(#colnames + CHAR(9), '') + column_name
FROM INFORMATION_SCHEMA.COLUMNS AS c;
SELECT ColNames = #colnames;
;--== 2. Using STRING_AGG
SELECT ColNames = STRING_AGG(c.COLUMN_NAME , CHAR(9))
FROM INFORMATION_SCHEMA.COLUMNS AS c;
;--== 3. Using FOR XML PATH
SELECT ColNames =
(SELECT c.COLUMN_NAME+CHAR(9) FROM INFORMATION_SCHEMA.COLUMNS AS c FOR XML PATH(''));
Results:
If we switch to Results as Text:
Now we get (note the tabs):
I'm looking for a way to get the list of all json attributes across all my PostgreSQL tables dynamically.
I have Query 1 which would generate a list of sql statements, and then run that sql statements to get the final output all in one go (like the dynamic SQL concept in SQL server).
Query 1 looks like this :
create temporary table test (ordr int, field varchar(1000));
-- Step 1 Create temp table to insert all table/col/json attrbute info
insert into test(ordr,field)
select 0 ordr,'create temporary table temp_table
( table_schema varchar(200)
,table_name varchar(200)
,column_name varchar(200)
,json_attribute varchar(200)
,data_type varchar(50)
);'
union
-- Non json type columns
select 1 ordr, 'insert into temp_table(table_name, column_name,data_type,json_attribute)'
union
-- Json columns with data like json object
select
3 ordr,
concat('select distinct ''', t.table_name, ''' tbl, ''', c.column_name, ''' col, ''' , c.data_type,''' data_type, '
,'jsonb_object_keys(', c.column_name, ') json_attribute', ' from ', t.table_name,
' where jsonb_typeof(' , c.column_name, ') = ''object'' union') AS field
from information_schema.tables t
join information_schema.columns c on c.table_name = t.table_name
where t.table_schema not in ('information_schema', 'pg_catalog')
--and table_type = 'BASE TABLE'
and c.data_type ='jsonb';
--final sql statements to build temp table
--copy all the column "txt" to a separate window and execute it, it will create a temp table "temp_table" which will have all tables/cols/json attributes
select ordr
,(case when t.ordr = (select max(t2.ordr) from test t2) then replace(field,'union','') else field end) txt
from test t
union
select 9999, ';select * from temp_table;'
order by 1 ;
Query 1 output : This is a list of sql statements
I'm looking for a way to run the Query 1 & Query 1 output which would get me the final output all in one go.
Any lead or guidance will be really appreciated.
As in topic, I would like to know how can I check for a column being non-nullable?
For oracle I have:
SELECT Nullable
FROM user_tab_columns
WHERE table_name = 'TOP_VALIDATION_RULE'
AND column_name = 'ERROR_LEVEL'
but how to transform it for postgresql?
I tried something like this, but getting ERROR: column "is_nullable" does not exist:
SELECT is_nullable
FROM information_schema.tables
WHERE table_name = 'TOP_VALIDATION_RULE'
AND column_name = 'ERROR_LEVEL'
///EDIT
After modification:
SELECT is_nullable
FROM information_schema.columns
WHERE table_name = 'TOP_VALIDATION_RULE'
AND column_name = 'ERROR_LEVEL'
I get:
Use pg_attribute to check the column is NULLABLE OR NOT
SELECT attnotnull FROM pg_attribute WHERE attname = 'ERROR_LEVEL'
Note: The above query will return more than one row if the ERROR_LEVEL column appears in more than one table in the database.
I have a table which has few columns. I got the name of columns by getting it as an array_agg and then array_to_string. Like below:
"hospitalaccountrecord,locationname,patientkey,inpatientadmitdatetime,readmission,no_null_days_btw_admissions,cohort_assignment,admit_mon_feb,admit_mon_mar,admit_mon_apr,admit_mon_may,admit_mon_june,admit_mon_july,admit_mon_aug,admit_mon_sep,admit_mon_oct,a (...)"
The code I used was this:
select array_to_string(array_agg(column_name::text), ',')
from
(
select column_name
from
information_schema.columns
where table_schema='a' and
table_name = 'b'
order by columns.ordinal_position
) as v;
What I am looking for is the same thing but each column name should be enclosed in ''. Like
'hospitalaccountrecord','locationname','patientkey'
and so on.
Don't need two SELECTs, only
select string_agg(''''|| your_column_name ||'''', ',')
should do the job.
select string_agg(quoted_column_name, ',')
from
(
select '''' || column_name || '''' as quoted_column_name
from
information_schema.columns
where table_schema='a' and
table_name = 'b'
order by columns.ordinal_position
) as v;
I'm using PostgreSQL and I want to create a query that will display all column_names in a specific table.
Schema: codes
Table Name: watch_list
Here are the column_names in my table:
watch_list_id, watch_name, watch_description
I tried what I found in the web:
SELECT *
FROM information_schema.columns
WHERE table_schema = 'codes'
AND table_name = 'watch_list'
It output is not what I wanted. It should be:
watch_list_id, watch_name, watch_description
How to do this?
If you want all column names in a single row, you need to aggregate those names:
SELECT table_name, string_agg(column_name, ', ' order by ordinal_position) as columns
FROM information_schema.columns
WHERE table_schema = 'codes'
AND table_name = 'watch_list'
GROUP BY table_name;
If you remove the condition on the table name, you get this for all tables in that schema.
SELECT table_name FROM information_schema.tables WHERE table_schema='public'