Why does a PostgreSQL SELECT query return different results when a schema name is specified? - postgresql

I have a PostgreSQL database table with 4 columns - labeled column_a, column_b, etc. I want to query this table with a simple select query:
select * from table_name;
I get a handful of results looking like:
column_a | column_b
---------+---------
'a value'|'b_value'
But when I use this query:
select * from schema_name.table_name;
I get the full result:
column_a | column_b | column_c | column_d
---------+----------+----------+---------
'a value'|'b value' |'c value' |'d_value'
Columns c and d were added at a later date, after initial table creation. My question is: Why would the database ignore the later columns when the schema name is left out of the select query?

Table names are not unique within a database in Postgres. There can be any number of tables named 'table_name' in different schemas - including the temporary schema, which always comes first unless you explicitly list it after other schemas in the search_path. Obviously, there are multiple tables named table_name. You must understand the role of the search_path to interpret this correctly:
How does the search_path influence identifier resolution and the "current schema"
The first table lives in a schema that comes before schema_name in your search_path (or schema_name is not listed there at all). So the unqualified table name is resolved to this table (or view). Check the list of tables named 'table_name' that your current role has access to in your database:
SELECT *
FROM information_schema.tables
WHERE table_name = 'table_name';
Views are just special tables with an attached RULE internally. They could play the same role as a regular table and are included in the above query.
Details:
How to check if a table exists in a given schema

Related

Db2: Query for searching table with different column name

In my database, all tables should have a column (let's say "abc") and I want to find out the tables which do not have this column. Do we have any such query to fulfill this requirement?
Database: Db2 v11.1 LUW
You can build a query against SYSCAT.COLUMNS (and SYSCAT.TABLES) to find those tables not having such column:
select tabname from syscat.tables t1
where not exists
(select colname from syscat.columns c
where c.tabname=t1.tabname and colname='foo')
and tabname like 'SYSX%'
Above is just an example and not optimized.
Non-system tables only. Column name must be in uppercase, unless you specified the column name as “abc” (in double quotes) upon the table creation intentionally.
select tabschema, tabname
from syscat.tables t
where not exists
(
select 1
from syscat.columns c
where c.tabschema=t.tabschema and c.tabname=t.tabname
and c.colname='ABC'
)
and tabschema not like 'SYS%'
and type='T';

Query Constraint Clauses With Schema and Table (Postgres)

I am trying to query the constraint clauses along with schema and table in postgres. I've gotten as far as identifying information_schema.check_constraints as a useful table. The problem is that doing
select *
from information_schema.check_constraints
Results in constraint_catalog, constraint_schema, constraint_name, check_clause. The check_clause is what I want and this table also gives me the constraint_schema. However, it does not give the table that this constraint is defined on. In my current database, I have constraints with the same name defined on different tables within the same schema (which is in it of itself perhaps poor design but what I need to deal with). Is it possible to get the table name here as well?
select
conname,
connamespace::regnamespace as schemaname,
conrelid::regclass as tablename,
consrc as checkclause,
pg_get_constraintdef(oid) as definition
from
pg_constraint
where
contype = 'c'
and conrelid <> 0; -- to get only table constraints
About pg_constraint
About Object Identifier Types

How do you filter table column names in postgres?

The use case is, say you have a table with a lot of columns (100+) and you want to see if a certain column name exists in the table. Another use case is, say there is a name scheme for the columns in the table that allows me to search for a term that will show all fields with that name - e.g. all fields related to a payment card are prefixed with "card_".
In MySQL I could handle both cases above by doing a show fields in <table_name> like '%<search_term>%'. I've googled for a solution but have only found results related to filtering actual table names and showing table schemas (e.g. \d+), which is not what I am looking for. I've also tried variations of the MySQL command in the psql shell, but no luck.
I'm looking for a way to do this with SQL or with some other Postgres built-in way. Right now I'm resorting to copying the table schema to a text file and searching through it that way.
You can query information_schema.columns using table_name and column_name. For example:
>= select table_name, column_name
from information_schema.columns
where table_name = 'users'
and column_name like '%password%';
table_name | column_name
------------+------------------------
users | encrypted_password
users | reset_password_token
users | reset_password_sent_at

How to query two tables in psql to check if data in one table exists in another?

I want to write a psql query where I want to find all the data in row 1 of Table A that don't exist in row 2 of Table B?
I'm a little lost as to what you are asking about, but maybe the PostgreSQL's EXCEPT [ALL] operator is what you're looking for, e.g.
select column_a, column_b, column_c
from table_A
except all
select column_a, column_b, column_c
from table_B
;
Refer PostgrSQL Documentaion

How to determine the OID of a Postgres table?

Does anyone know how to find the OID of a table in Postgres 9.1?
I am writing an update script that needs to test for the existence of a column in a table before it tries to add the column. This is to prevent errors when running the script repeatedly.
To get a table OID, cast to the object identifier type regclass (while connected to the same DB):
SELECT 'mytbl'::regclass::oid;
This finds the first table (or view, etc.) with the given name along the search_path or raises an exception if not found.
Schema-qualify the table name to remove the dependency on the search path:
SELECT 'myschema.mytbl'::regclass::oid;
In Postgres 9.4 or later you can also use to_regclass('myschema.mytbl'), which doesn't raise an exception if the table is not found:
How to check if a table exists in a given schema
Then you only need to query the catalog table pg_attribute for the existence of the column:
SELECT TRUE AS col_exists
FROM pg_attribute
WHERE attrelid = 'myschema.mytbl'::regclass
AND attname = 'mycol'
AND NOT attisdropped -- no dropped (dead) columns
-- AND attnum > 0 -- no system columns (you may or may not want this)
;
The postgres catalog table pg_class is what you should look at. There should be one row per table, with the table name in the column relname, and the oid in the hidden column oid.
You may also be interested in the pg_attribute catalog table, which includes one row per table column.
See: http://www.postgresql.org/docs/current/static/catalog-pg-class.html and http://www.postgresql.org/docs/current/static/catalog-pg-attribute.html
SELECT oid FROM pg_class WHERE relname = 'tbl_name' AND relkind = 'r';
Just to complete the possibilities I'd like to add that there exists a syntax for dropping columns in order to no error out:
ALTER TABLE mytbl
DROP COLUMN IF EXISTS mycol
See http://www.postgresql.org/docs/9.0/static/sql-altertable.html
Then you can safely add your column.