I'd like to select all table names where one of columns has a name user_id.
Is it possible in PostgreSQL?
Try this:
select table_name
from information_schema.columns
where column_name = 'user_id'
It should work OK.
Make sure to include the schema name. Your table name can be ambiguous without it. May even lead to harmful confusion:
SELECT table_schema, table_name
FROM information_schema.columns
WHERE column_name = 'user_id';
The information schema is only good if you need cross-RDBMS portability, which is rarely needed and rarely works. I'd rather query the catalog tables directly. Faster and shorter:
SELECT attrelid::regclass
FROM pg_attribute
WHERE attname = 'user_id';
And be sure that you are connected to the same database.
Related
I usually have to check datatype a particular tablecolumn via a sql code, for which I use
desc tablename
Some tables I look at have a lot of columns, and I think it would be nice if there's a way to get the description for only a particular column (or columns).
Does anyone know of a way to get that info for only a particular (set of) column(s)?
For example something like the beneath would be nice, and possibly there already is?
desc tablename.column_name
Adding on the answer provided by Radim , You not only need the datatype but also the precision for when it comes to datatypes like varchar2(20).
Select TABLE_NAME,COLUMN_NAME,DATA_PRECISION From ALL_TAB_COLUMNS
Where TABLE_NAME = UPPER('TABLE_NAME') and COLUMN_NAME = UPPER('COLUMN_NAME')
Use ALL_TAB_COLUMNS system catalog views
Select COLUMN_NAME, DATA_TYPE From ALL_TAB_COLUMNS
Where TABLE_NAME = UPPER('TAB NAME') and COLUMN_NAME = UPPER('COL NAME')
I am facing an issue when fetching column names for the particular table
I wrote the following query
SELECT column_name
FROM all_tab_cols
WHERE Table_name like 'tabelname';
But what happen in table have 54 columns but when I run that code 224 columns coming. I don't known why.
Assuming Oracle, not SQL Server.
all_tabl_cols shows columns from all tables the current user has access to, not those owned by the current user. If the same table exists in different schema, all of them will be shown.
The LIKE operator makes no sense if you don't use a wildcard pattern with it. It would be cleaner to use Table_name = 'tabelname' instead.
Oracle stores table names in UPPERCASE (unless you created them using those dreaded double quotes). And string comparison is case-sensitive in Oracle. So you must compare the the content of the column table_name with an uppercase name-
You can either use user_tab_cols instead of all_tab_cols
SELECT column_name
FROM user_tab_cols
WHERE table_name = 'THE_TABLE';
or you need to specify the owner:
SELECT column_name
FROM all_tab_cols
WHERE table_name = 'THE_TABLE'
AND owner = user;
SELECT column_name
FROM all_tab_cols
WHERE table_name = 'VERIFICATION'
AND owner = 'APPDB'
AND column_name NOT IN ( 'password', 'version', 'id' )
Is it possible to retrieve all data in columns containing a particular string? I do not have any control over the data structure and I rather shorten my code than to type everything if possible. As far as I know statements as LIKE and CONTAIN are only used to retrieve particular rows instead of columns. Lets say I have a table with column names: time, run1, run2, run3, ....., run 34, I would like to use something like:
SELECT columns FROM [Tablename] WHERE columns CONTAIN 'run';
Is this possible?
Thanks!
Use like.
In Oracle, you could do
SELECT column_name
from all_tab_columns
where table_name = 'YOUR_TABLE'
and lower(column_name) like 'run%'
In SQL Server, you could do
SELECT column_name
from information_schema.columns
where table_name = 'YOUR_TABLE_NAME'
and lower(column_name) like 'run%'
I want to fetch all columns of a table except of columns of type serial. The closest query to this problem I was able to come up with this one:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1' AND column_default NOT LIKE 'nextval%'
But the problem is its also excluding/filtering rows having empty values for column_default.I don't know why the behaviour of Postgres is like this. So I had to change my query to something like this:
SELECT column_name FROM information_schema.columns
WHERE table_name = 'table1'
AND ( column_default IS NULL OR column_default NOT LIKE 'nextval%')
Any better suggestions or rationale behind this are welcome.
About null
'anything' NOT LIKE null yields null, not true.
And only true qualifies for filter expressions in a WHERE clause.
Most functions return null on null input (there are exceptions). That's the nature of null in any proper RDBMS.
If you desire a single expression, you could use:
AND (column_default LIKE 'nextval%') IS NOT TRUE;
That's hardly shorter or faster, though. Details in the manual.
Proper query
Your query is still unreliable. A table name alone is not unique in a Postgres database, you need to specify the schema name in addition or rely on the current search_path to find the first match in it:
Related:
How does the search_path influence identifier resolution and the "current schema"
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'hstore1'
AND table_schema = 'public' -- your schema!
AND (column_default IS NULL
OR column_default NOT LIKE 'nextval%');
Better, but still not bullet-proof. A column default starting with 'nextval' does not make a serial, yet. See:
Auto increment table column
To be sure, check whether the sequence in use is "owned" by the column with pg_get_serial_sequence(table_name, column_name).
I rarely use the information schema myself. Those slow, bloated views guarantee portability across major versions - and aim at portability to other standard-compliant RDBMS. But too much is incompatible anyway. Oracle does not even implement the information schema (as of 2015).
Also, useful Postgres-specific columns are missing in the information schema. For this case I might query the the system catalogs like this:
SELECT *
FROM pg_catalog.pg_attribute a
WHERE attrelid = 'table1'::regclass
AND NOT attisdropped -- no dropped (dead) columns
AND attnum > 0 -- no system columns
AND NOT EXISTS (
SELECT FROM pg_catalog.pg_attrdef d
WHERE (d.adrelid, d.adnum) = (a.attrelid, a.attnum)
AND d.adsrc LIKE 'nextval%'
AND pg_get_serial_sequence(a.attrelid::regclass::text, a.attname) <> ''
);
Faster and more reliable, but less portable.
The manual:
The catalog pg_attrdef stores column default values. The main
information about columns is stored in pg_attribute (see below). Only
columns that explicitly specify a default value (when the table is
created or the column is added) will have an entry here.
'table1'::regclass uses the search_path to resolve the name, which avoids ambiguity. You can schema-qualify the name to overrule: 'myschema.table1'::regclass.
Related:
Find the referenced table name using table, field and schema name
Get the default values of table columns in Postgres?
I think you can use :
SELECT column_name *FROM* information_schema.columns
WHERE table_name = 'table1'
AND ( nvl(column_default,0) *NOT LIKE* 'nextval%');
I know I can return an empty table using the following query :
select * from tbFoo where 1=2
but that code doesn't look nice to me.
Is there a 'standard' way of doing this?
If you're wondering why I want to do such a strange thing, it's because I can't name the datatables I return from a stored procedure, so I need empty placeholders.
Having just run both:
SELECT TOP 0 * FROM Table
and
SELECT * FROM Table WHERE 1=0
They produce exactly the same execution plan.
Most of the time I see 1=0 but yes thats pretty much the standard approach when you really have to. Although really having to is rare.
What you really need is information_schema, using it will allow you to find out the definition of a table.
You don't mention which database you are using, so here is a link about information_schema Support in MySQL, PostgreSQL (and MSSQL, Oracle, Etc)
An example from the site;
SELECT table_name, column_name, is_nullable, data_type, character_maximum_length
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'
In your case, all you need are the column names;
SELECT column_name
FROM INFORMATION_SCHEMA.Columns
WHERE table_name = 'employees'