when doing INSERT INTO ... SELECT ... to load data from a table from another one. Does the INSERT start before the end of the SELECT?
example: INSERT INTO films SELECT * FROM tmp_films WHERE date_prod < '2004-05-07';
First, the data is collected from the SELECT query. Afterwards, this data is given to the INSERT statement.
Also check out the docs here: SQL-INSERT
I want to cache result of big select query for further use. The idea is to use temporary table (I believe that it persists for session or at least for transaction):
CREATE TEMP TABLE cache AS (SELECT * FROM t)
but when cache is already created I encounter following error:
Invalid operation: relation "cache" already exists;
There are no IF NOT EXISTS condition for CREATE TEMP TABLE ... AS statement. So question is, is there some workaround for this case?
If you want to store just results for last "big query" in session then
Drop table if exists cache;
Create temp table cache as
select * from t where "your's conditions";
Dropping the cache table before will not block your creating table statement.
If you want to store results for all of your "big queries" then you will need some extra info in the naming of your cache.
You could check if temp table already exists in if statment
IF (select count(*)
from information_schema.tables
where table_name'cache'
and table_schema like 'pg_temp%')=0 THEN
create temp table cache as
select * from t where "your's conditions";
ELSE
select * from cache where "your's conditions";
END;
I have a Postgres database. In this database is have a Table with Polygons.
Named: dg_mm_polygons.
I have created a Select and WHERE Query:
SELECT * FROM dg_geodata.dg_mm_polygons WHERE OFFSHORE = 2;
If I execute this it works as i want.
I want to let the table dg_geodata.dg_mm_polygons be as it is.
My Question:
I want to create/get a new table dg_geodata.dg_mm_polygons_2. If data is saved in dg_geodata.dg_mm_polygons in needs to be given/get to the table dg_geodata.dg_mm_polygons_2.
Is it possible to do this?
You can use a CREATE TABLE AS statement (https://www.postgresql.org/docs/current/static/sql-createtableas.html)
In your case, the following statement will create a new table called "dg_mm_polygons2", which will be populated with data from your existing "dg_mm_polygons" table where OFFHSORE = 2.
CREATE TABLE dg_geodata.dg_mm_polygons2 AS SELECT * FROM dg_geodata.dg_mm_polygons WHERE OFFSHORE = 2;
it sounds like you want to create a view dg_geodata.dg_mm_polygons_2 which contains only a subset of data from dg_geodata.dg_mm_polygons
create view dg_geodata.dg_mm_polygons_2 as
select *
from dg_geodata.dg_mm_polygons
WHERE OFFSHORE = 2;
this will ensure that only values of offshore = 2 show up in dg_geodata.dg_mm_polygons_2. be carefult though, you can also insert update/delete from views just as you would from the original table.
I have a postgres DB and inside of it there are many schemas.
Each one of those schemas contains tables. For example:
Schema Name: personal has tables actions_takes, page_views etc
How can i write a SQL query or ActiveRecord query to query the table inside the schema?
Something like:
select * from actions_takes where user_id = 123;
I can create a model for each table and query it that way, but i want to write a script that passed a user goes over all tables and get the data for that user.
in pgAdmin 4 web console should use double quotation marks like following select statement
SELECT "col1", "col2"
FROM "schemaName".profile;
Point to specific table within a given schema using a dot notation schema.table_name. In your case it translates to
select * from personal.actions_takes where user_id = 123;
For me this query worked : select * from schemaName."Table_Name"
How can I find the table creation time in PostgreSQL?
Example: If I created a file I can find the file creation time like that I want to know the table creation time.
I had a look through the pg_* tables, and I couldn't find any creation times in there. It's possible to locate the table files, but then on Linux you can't get file creation time. So I think the answer is that you can only find this information on Windows, using the following steps:
get the database id with select datname, datdba from pg_database;
get the table filenode id with select relname, relfilenode from pg_class;
find the table file and look up its creation time; I think the location should be something like <PostgreSQL folder>/main/base/<database id>/<table filenode id> (not sure what it is on Windows).
You can't - the information isn't recorded anywhere. Looking at the table files won't necessarily give you the right information - there are table operations that will create a new file for you, in which case the date would reset.
I don't think it's possible from within PostgreSQL, but you'll probably find it in the underlying table file's creation time.
Suggested here :
SELECT oid FROM pg_database WHERE datname = 'mydb';
Then (assuming the oid is 12345) :
ls -l $PGDATA/base/12345/PG_VERSION
This workaround assumes that PG_VERSION is the least likely to be modified after the creation.
NB : If PGDATA is not defined, check Where does PostgreSQL store the database?
Check data dir location
SHOW data_directory;
Check For Postgres relation file path :
SELECT pg_relation_filepath('table_name');
you will get the file path of your relation
check for creation time of this file <data-dir>/<relation-file-path>
I tried a different approach to get table creation date which could help for keeping track of dynamically created tables. Suppose you have a table inventory in your database where you manage to save the creation date of the tables.
CREATE TABLE inventory (id SERIAL, tablename CHARACTER VARYING (128), created_at DATE);
Then, when a table you want to keep track of is created it's added in your inventory.
CREATE TABLE temp_table_1 (id SERIAL); -- A dynamic table is created
INSERT INTO inventory VALUES (1, 'temp_table_1', '2020-10-07 10:00:00'); -- We add it into the inventory
Then you could get advantage of pg_tables to run something like this to get existing table creation dates:
SELECT pg_tables.tablename, inventory.created_at
FROM pg_tables
INNER JOIN inventory
ON pg_tables.tablename = inventory.tablename
/*
tablename | created_at
--------------+------------
temp_table_1 | 2020-10-07
*/
For my use-case it is ok because I work with a set of dynamic tables that I need to keep track of.
P.S: Replace inventory in the database with your table name.
I'm trying to follow a different way for obtain this.
Starting from this discussion my solution was:
DROP TABLE IF EXISTS t_create_history CASCADE;
CREATE TABLE t_create_history (
gid serial primary key,
object_type varchar(20),
schema_name varchar(50),
object_identity varchar(200),
creation_date timestamp without time zone
);
--delete event trigger before dropping function
DROP EVENT TRIGGER IF EXISTS t_create_history_trigger;
--create history function
DROP FUNCTION IF EXISTS public.t_create_history_func();
CREATE OR REPLACE FUNCTION t_create_history_func()
RETURNS event_trigger
LANGUAGE plpgsql
AS $$
DECLARE
obj record;
BEGIN
FOR obj IN SELECT * FROM pg_event_trigger_ddl_commands () WHERE command_tag in ('SELECT INTO','CREATE TABLE','CREATE TABLE AS')
LOOP
INSERT INTO public.t_create_history (object_type, schema_name, object_identity, creation_date) SELECT obj.object_type, obj.schema_name, obj.object_identity, now();
END LOOP;
END;
$$;
--ALTER EVENT TRIGGER t_create_history_trigger DISABLE;
--DROP EVENT TRIGGER t_create_history_trigger;
CREATE EVENT TRIGGER t_create_history_trigger ON ddl_command_end
WHEN TAG IN ('SELECT INTO','CREATE TABLE','CREATE TABLE AS')
EXECUTE PROCEDURE t_create_history_func();
In this way you obtain a table that records all the creation tables.
--query
select pslo.stasubtype, pc.relname, pslo.statime
from pg_stat_last_operation pslo
join pg_class pc on(pc.relfilenode = pslo.objid)
and pslo.staactionname = 'CREATE'
Order By pslo.statime desc
will help to accomplish desired results
(tried it on greenplum)
You can get this from pg_stat_last_operation. Here is how to do it:
select * from pg_stat_last_operation where objid = 'table_name'::regclass order by statime;
This table stores following operations:
select distinct staactionname from pg_stat_last_operation;
staactionname
---------------
ALTER
ANALYZE
CREATE
PARTITION
PRIVILEGE
VACUUM
(6 rows)