Delete .. from .. join, same syntax for postgresql and oracle - postgresql

I need to execute the same exact query on oracle and postgresql, in which i need to delete rows from table 1, using a join on table 2.
I already had a working query, but it stopped working for oracle with 1000+ results in the "IN" statement.
delete from t1
where
t1.oid IN
(SELECT oid from t2 WHERE [condition])
I've read about joins but postgresql uses the "using" keyword instead
DELETE [target table]
FROM [table1]
INNER JOIN [table2]
ON [table1.[joining column] = [table2].[joining column]
WHERE [condition]
Any help is appreciated, thanks

Oracle does not support a JOIN or USING or something similar for the DELETE statement. Your only choices are IN or EXISTS, if you need something that works on Postgres and Oracle.
If an IN condition is too slow then try an EXISTS condition:
delete from t1
where exists (select *
from t2
where t2.oid = t1.oid
and [condition])

You can use and multi-dimensional IN expression (which should work up to 100,000 items):
DELETE FROM t1
WHERE ( t1.oid, 1 ) IN ( SELECT oid, 1 FROM t2 );
or EXISTS (which should work for any volume of rows):
DELETE FROM t1
WHERE EXISTS ( SELECT 1 FROM t2 WHERE t1.oid = t2.oid );
And add the WHERE condition into the sub-query as required.
PostgreSQL db<>fiddle
Oracle db<>fiddle

Related

Setting the Postgres 9.6 Current Sequence Values of All Tables to Max ID values of all Parent Tables [duplicate]

This question already has answers here:
How to bulk update sequence ID postgreSQL for all tables
(3 answers)
Closed last month.
Postgres allows for auto-increment of the Primary Key value SERIAL is used at DDL. With this, a sequence property for the table is also created along with the table. However, when tuples are inserted manually, the sequence current value does not get updated.
For One table at a time we can use SQL like this
SELECT setval('<table>_id_seq', COALESCE((SELECT MAX(id) FROM your_table), 1), false); wherein we need to manually set the <table>_id_seq' and id' attribute name.
The problem becomes labourious if there are multiple tables. So is there any generalised method to set current value for all sequences to the MAX(<whatever_sequence_attribute_is>)?
Yup! Got it
First run the following SQL
SELECT 'SELECT setval(' || quote_literal(quote_ident(sequence_namespace.nspname) || '.' || quote_ident(class_sequence.relname)) || ', COALESCE((SELECT MAX(' ||quote_ident(pg_attribute.attname)|| ') FROM ' || quote_ident(table_namespace.nspname)|| '.'||quote_ident(class_table.relname)|| '), 1), false)' || ';' FROM pg_depend INNER JOIN pg_class AS class_sequence ON class_sequence.oid = pg_depend.objid AND class_sequence.relkind = 'S' INNER JOIN pg_class AS class_table ON class_table.oid = pg_depend.refobjid INNER JOIN pg_attribute ON pg_attribute.attrelid = class_table.oid AND pg_depend.refobjsubid = pg_attribute.attnum INNER JOIN pg_namespace as table_namespace ON table_namespace.oid = class_table.relnamespace INNER JOIN pg_namespace AS sequence_namespace ON sequence_namespace.oid = class_sequence.relnamespace ORDER BY sequence_namespace.nspname, class_sequence.relname;
The result window will show as many SQL statements as sequences are there in the DB. Copy all the SQL statements and Execute all. The current value of all sequences will get updated.
Note: Please Note that the major SQL will only generate SQLs and WILL NOT UPDATE the sequences. One has to copy all the SQL Statements from the Result and execute.

Update query with null left join condition in postgreSQL

I'm currently migrating from SQL Server to PostgreSQL and got confuse with update query in postgres.
I have query like this in SQL Server:
UPDATE t1
SET col1 = 'xx'
FROM table1 t1
LEFT JOIN table2 t2 ON t1.id = t2.id
WHERE t2.id is null
how do you do this in postgres?
thanks in advance
The left join is used to simulate a "NOT EXISTS" condition, so you can rewrite it to:
update table1 t1
set col1 = 'xx'
where not exists (select *
from table2 t2
where t1.id = t2.id);
As a side note: Postgres works differently than SQL Server and in general you should not repeat the target table of an UPDATE statement in the FROM clause in Postgres.

Apply MAX(LENGTH) on all columns of a table

I want to check the MAX(LENGTH) of all VARCHAR columns of my Redshift table, so I have an idea of a better limitation I could put on the column sizes. (Right now all columns are VARCHAR(65535))
I can write a query like:
SELECT MAX(LENGTH(col1)), MAX(LENGTH(col2)), ...
FROM my_table
But isn't there a way I could write my query so it basically says "apply this for every column"? I've tried the answer from this post but it seems it only applies to classic PostgreSQL
You can use the following SQL the generate your select
select sql from (
select 1 o, 'select ' sql
union
select 2, 'max(length('+attname+')),'
from pg_class c
join pg_attribute a on c.oid = a.attrelid
where relname = '<your_table>'
and attnum > 0
union
select 3, 'from <your_table>'
)
order by o
The output will look like this
select
max(length(col1)),
max(length(col2)),
...
max(length(coln)), -- <- remove the last comma
from <your_table>
You can run this sql to get all max lengths from your table
Please let me know if this helps you.

PostgreSQL Record Reordering using Update with a Sub-Select

I found this solution on the SQL Server forum on how to reorder records in a table.
UPDATE SomeTable
SET rankcol = SubQuery.Sort_Order
FROM
(
SELECT IDCol, Row_Number() OVER (ORDER BY ValueCOL) as SORT_ORDER
FROM SomeTable
) SubQuery
INNER JOIN SomeTable ON
SubQuery.IDCol = SomeTable.IDCol
When I try doing the same on PostgreSQL, I get an error message -
ERROR: table name "sometable" specified more than once
Any help will be appreciated.
Thanks!
You don`t need to explicitly join SomeTable, how cool is that? :)
UPDATE SomeTable
SET rankcol = SubQuery.Sort_Order
FROM
(
SELECT IDCol, Row_Number() OVER (ORDER BY ValueCOL) as SORT_ORDER
FROM SomeTable
) SubQuery
where SubQuery.IDCol = SomeTable.IDCol
remark: Postgres is case insensitive, better use lower-case, like row_number, sort_order, id_col , etc.

Select query to find the unmatched records from selected values using in function in Oracle 10g

I am using IN clause for column "job_no". In this in clause i checking 1000 values, query retreiving the values but some of the job number are not existed, then how to find unmattched values in the in clause.
assuming you really are using Oracle:
create type table_of_integers is table of integer;
/
select * from table(table_of_integers(1, 2, 3))
where column_value not in (select job_no from my_table);
or you should be able to achieve the same thing using an outer join, such as this example for postgres:
select *
from (select unnest(array[1, 2, 3]) as job_no) j
left outer join my_table using(job_no)
where my_table.job_no is null;
Insert the values into a temporary table instead and do a LEFT OUTER JOIN to join with your data.