Postgres Where Statement for new Table - postgresql

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.

Related

How to write a select statement for a table in postgres that is inside a schema?

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"

Join a view to another table

Is it possible to join a view with another table in SQL? If so, how?
I have a query on Oracle db which has specific fields. I need to re create the same query on PostgreSQL but some of the data in the PostgreSQL query are coming from a view... And that view has missing information. It's a pretty complex view, so I don't want to NOT use it for now.
For example, in Oracle I do this:
SELECT
d.dos_id,
trunc(d.dos_creation, 'MM') as Cohorte,
sum(v.ver_etude + v.ver_direct) as encaissé
from t_dossier d
left outer join v_versement v
on v.dos_id = d.dos_id
In the Postgres one, I'm using a view. But the view does not return "dos_id" so I cannot explicitly join v_versement with the view.
Is there a way to force a view to return specific fields at runtime which weren't there when creating the view?
You can't force it
to return specific fields at runtime which weren't there when creating
the view
You can create or replace it with limitation:
https://www.postgresql.org/docs/current/static/sql-createview.html
CREATE OR REPLACE VIEW is similar, but if a view of the same name
already exists, it is replaced. The new query must generate the same
columns that were generated by the existing view query (that is, the
same column names in the same order and with the same data types), but
it may add additional columns to the end of the list. The calculations
giving rise to the output columns may be completely different.
example:
t=# create view v2 as select now();
CREATE VIEW
Time: 36.488 ms
t=# create or replace view v2 as select now(),current_user;
CREATE VIEW
Time: 8.551 ms
t=# create or replace view v2 as select now()::text,current_user;
ERROR: cannot change data type of view column "now" from timestamp with time zone to text
Time: 0.430 ms
I guess I had not realised that I can actually use the view without creating it...
So I edited the SQL statement that makes up the view, added the fields that I needed and used the code of the view without having to create a new view (creating a new view would mean outsourcing it to another company, which would cost us money..)
Thanks :)

Postgres Text Search against a derived ts_vector

Somehow I've tricked myself into writing a full text search implementation on a database. I have a table that represents all the entities in my database, a table that represents all the tags, and a table representing the many to many relationship of tags to entities.
I wrote a query that groups all tag names for a given entity and concatenates them into a string, which I then transform into a ts_vector. That query looks like this:
SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue ecv, entity e
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.entityid
GROUP BY e.id;
The query returns results in this schema:
id | to_tsvector
1 | tag_a, tag_b, tag_c
2 | tag_b, tag_d, tag_e
Which is exactly what I'd like to match a ts_query against. I'm a noob at SQL though, and I am wondering if there is a way I can create a table that is continually updated with the results of the query I've written?
EDIT: I documented my eventual solution and system in this blog post http://tech.pro/tutorial/1142/building-faceted-search-with-postgresql
I think you want a VIEW.
CREATE VIEW my_tsearch_table AS
SELECT e.id, to_tsvector(c.publicname || ' ' || string_agg(cv.name, ' '))
FROM categoryvalue cv, entitycategoryvalue c=ecv, entity e
WHERE ccv.categoryvalueid = cv.id AND e.id = ecv.celebrityid
GROUP BY e.id;
Note, however, that you cannot add indexes to a view. This may be a problem with full-text search, as it's quite expensive to generate all those tsvectors for every search.
If you need to index that table, you are looking for a materialized view.
PostgreSQL does not support automatically maintained materialized views; you can't just CREATE MATERIALIZED VIEW and then add some indexes to it.
What you can do is manually maintain a materialized view using an ordinary table, an ordinary view created with your query, and some trigger functions.
Add a trigger function on each table that contributes to the view, and have that trigger function update (or insert into, or delete from, as appropriate) the materialized view based on updates made to that table. This can be complicated to get right in a concurrent environment, though, and it can be prone to lock-ordering deadlocks.
An alternative to a trigger-maintained view is to live with the materialized view getting a little out of date. Periodically create a new table, copy your ordinary view into the new table, add the desired indexes, then drop the old materialized view table and rename the new one to replace it.
See also:
http://wiki.postgresql.org/wiki/Materialized_Views
http://tech.jonathangardner.net/wiki/PostgreSQL/Materialized_Views

How to select and delete at once in DB2 for the queue functionality

I am trying to implement simple table queue in DB2 database. What I need
is to select and delete the row in the table at once so the multiple clients will not get the same row from the queue twice. I was looking for similiar questions but they describes the solution for another database or describes quite complicated solutions. I only need to select and delete the row at once.
UPDATE: I found on the web db2 clause like this, which look exactly like what i need - the select from delete: example:
SELECT * FROM OLD TABLE (DELETE FROM example WHERE example_id = 1)
but I am wondering if this statement is atomic if the two concurent request don't get the same result or delete the same row.
Something like this:
SELECT COL1, COL2, ... FROM TABLE WHERE TABLE_ID = value
WITH RR USE AND KEEP EXCLUSIVE LOCKS;
DELETE FROM TABLE WHERE TABLE_ID = value;
COMMIT;
If you're on DB2 for z/OS (Mainframe DB2) since version 9.1, or Linux/Unix/Windows (since at least 9.5, search for data-change-table-reference), you can use a SELECT FROM DELETE statement:
SELECT *
FROM OLD TABLE
(DELETE FROM TAB1
WHERE COL1 = 'asdf');
That would give you all the rows that were deleted.
Edit: Ooops, just saw your edit about using this type of statement. And as he said in the comment, two separate application getting the same row depends on your Isolation Level.

is there any temporary table after query?

After I got results from some query is there any name of temporary table created from those results???
No, but you can easily create a temporary table from the results of a select statement:
CREATE TEMPORARY TABLE temptablename AS
SELECT ...;
Then to get the result:
SELECT * FROM temptablename;