Update using left join in netezza - left-join

I need to perform a left join of two tables in netezza during an update. How can i achieve this ? Left join with three tables are working but not with two tables.
UPDATE table_1
SET c2 = t2.c2
FROM
table_1 t1
LEFT JOIN table_2.t1
ON t1.c1=t2.c1
LEFT JOIN table_3 t3
ON t2.c1=t3.c1
this works but
UPDATE table_1
SET c2 = t2.c2
FROM table_1 t1
LEFT JOIN table_2.t1
ON t1.c1=t2.c1
this says like trying to update multiple columns.
Thanks,
Manirathinam.

When performing an UPDATE TABLE with a join in Netezza, it's important to understand that the table being updated is always implicitly INNER JOINed with the FROM list. This behavior is documented here.
Your code is actually joining table_1 to itself (one copy with no alias, and one with t1 as an alias). Since there is no join criteria between those two versions of table_1, you are getting a cross join which is providing multiple rows that are trying to update table_1.
The best way to tackle an UPDATE with an OUTER join is to employ a subselect like this:
TESTDB.ADMIN(ADMIN)=> select * from table_1 order by c1;
C1 | C2
----+----
1 | 1
2 | 2
3 | 3
(3 rows)
TESTDB.ADMIN(ADMIN)=> select * from table_2 order by c1;
C1 | C2
----+----
1 | 10
3 | 30
(2 rows)
TESTDB.ADMIN(ADMIN)=> UPDATE table_1 t1
SET t1.c2 = foo.c2
FROM (
SELECT t1a.c1,
t2.c2
FROM table_1 t1a
LEFT JOIN table_2 t2
ON t1a.c1 = t2.c1
)
foo
WHERE t1.c1 = foo.c1;
UPDATE 3
TESTDB.ADMIN(ADMIN)=> select * from table_1 order by c1;
C1 | C2
----+----
1 | 10
2 |
3 | 30
(3 rows)

Related

SQL check value from another table

I've got multiple tables
I made my query like this :
SELECT a.creation, b.caseno, c.instanceno
FROM TableB b
JOIN TableA a
ON a.caseno = b.caseno
JOIN TableC c
ON c.caseno = b.caseno
WHERE a.creation BETWEEN '2021-01-01' AND '2021-12-31'
I've got TableD who contains the following column
| InstanceNo | Position | Creation | TaskNo |
The idea is to add a new colum (result) on my query.
If instance from c.instanceno exist on tableD and taskno is 30 or 20, in that case i would like the d.creation but for the max(position).
If not the value null is enough for the column result.
SELECT a.creation, b.caseno, c.instanceno, d.creation
FROM TableB b
JOIN TableA a
ON a.caseno = b.caseno
JOIN TableC c
ON c.caseno = b.caseno
LEFT JOIN (SELECT MAX(position) position, instanceno, creation, taskno FROM TableD GROUP BY instanceno, creation, taskno) d
ON d.instanceno = c.instanceno
AND d.taskno in (20,30)
WHERE a.creation BETWEEN '2021-01-01' AND '2021-12-31'

Choose "strongest" intersected area

I have a materialized view which is the result of a spatial joint using st_intersect of two polygons layers. Table1 and table2, features of table1 can be itnersected for few polygons of table2, thsi is how i create the mview:
SELECT g.field1,
att.ogc_fid,
st_intersection(g.geom, att.geom) AS intersect_geom,
st_area(g.geom) AS geom_area,
st_area(st_intersection(g.geom, att.geom)) AS intersect_area
FROM table1 g
JOIN table2 att ON g.geom && att.geom;
field1 | ogc_fid | intersect_geom| geom_area | intersect_area
aa12345 1 123123 123131 1313123414
aa12345 3 1 1 1
bb12345 2 4124141 13141 14415151
bb12345 1 1243141414 1231313 13131323
From this mview i want to pick just the strongest intersected area and join to a description coming from table2.. I have tried the code below:
select a.*, b.desc
from table1 a
left join lateral
(
select desc
table2
where table2.ogc_fid= table1.ogc_fid
order by (intersect_area/geom_area) DESC NULLS LAST
limit 1
) b
field1 | ogc_fid | intersect_geom| geom_area | intersect_area | desc
aa12345 1 123123 123131 1313123414 desc for 1
bb12345 2 4124141 13141 14415151 desc for 2
but results here are not the expected ones. I went through other threads but im stuck when trying to get just one result (the strongest), and create a table with those strongest intersection so for one feature in table one i have the most strongest intersected.
If I understood you right, you have done the hard bit already. You just need to pick the one record per field from the view and join with table2... So try this:
SELECT DISTINCT ON (field1) field1, m.ogc_fid, b.desc FROM
mview AS m
INNER JOIN table2 AS b ON b.ogc_fid = m.ogc_fid
ORDER BY field1, (intersect_area/geom_area) DESC

Query table with multiple joined values

I've created a query that joins six tables:
SELECT a.accession, b.value, c.name, d.description, e.value, f.seqlen, f.residues
FROM chado.dbxref a inner join chado.dbxrefprop b on a.dbxref_id = b.dbxref_id
inner join chado.biomaterial d on b.dbxref_id = d.dbxref_id
inner join chado.feature f on d.dbxref_id = f.dbxref_id
inner join chado.biomaterialprop e on d.biomaterial_id = e.biomaterial_id
inner join chado.contact c on d.biosourceprovider_id = c.contact_id;
The output:
I'm currently working with a PostgreSQL schema called Chado (http://gmod.org/wiki/Chado_Tables). My attempts to comply with the preexisting schema have led me to deposit multiple joined values within the same table (two different values within the dbxrefprop table, three different values within the biomaterialprop table). Querying the database results in a substantial amount of redundant output. Is there a way for me to reduce output redundancy by modifying my query statement? Ideally, I'd like the output to resemble the following:
test001 | GB0101 | source011 | Faaberg,K.; Lyoo,K.; Korol,D.M. | serum | T1 | Iowa, USA | 01 Jan 2005 | 1234 | AUGAACGCCUUGCAUUACUAUGACUAUGAUU
Working query statement:
SELECT a.accession, string_agg(distinct b.value, ' | ' ORDER BY b.value) AS bvalue_list, c.name, d.description, string_agg(distinct e.value, ' | ' ORDER BY e.value) AS evalue_list, f.seqlen, f.residues
FROM chado.dbxref a INNER JOIN chado.dbxrefprop b ON a.dbxref_id = b.dbxref_id
INNER JOIN chado.biomaterial d ON b.dbxref_id = d.dbxref_id
INNER JOIN chado.feature f ON d.dbxref_id = f.dbxref_id
INNER JOIN chado.biomaterialprop e ON d.biomaterial_id = e.biomaterial_id
INNER JOIN chado.contact c ON d.biosourceprovider_id = c.contact_id
GROUP BY a.accession, c.name, d.description, f.seqlen, f.residues;

How to perform != or <> in postgresql

i need to fetch the table1 content which is not present in the table2 i dont think which is possible by <> or != operator so can any one help me here
select t1._id, t1."categoryName", t1.company_id, t1.active from table1 t1
inner join table2 t2 on t1._id <> t2.category_id
inner join table3 t3 on t2 .department_id <> t3 ._id where t3._id = 1
for example:
a collage can have 10 departments , students enrolled to 5 department which is present 1 collage
table1 is dept
table 3 is col
table 2 looks like this:
col_id| dept_id | student_id
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
1 | 4 | 4
1 | 5 | 5
i need to fetch rest of the dept_id which is not present in table 2
i need to fetch the table1 content which is not present in the table2
Use a not exists query, something like this:
select *
from table1 t1
where not exists (select *
from table2 t2
where t1._id = t2.category_id)
Note sure how table3 relates to the question "not present in table2"
try not in, or outer join, like here:
select t1._id, t1."categoryName", t1.company_id, t1.active
from table1 t1
left outer join table2 t2 on t1._id = t2.category_id
left outer join table3 t3 on t2 .department_id = t3 ._id
where t3._id = 1
and t2.category_id is null
and t3 ._id is null
yep i got a solution to my question from dbastackexchange this might help others so pasting here
select
cat._id,
cat.cat_name
from
cat
where
not exists(
select
*
from
deptcat
inner join dept on(
dept._id = deptcat.dept_id
)
where
deptcat.cat_id = cat._id
and dept._id = 1
)

Join on a query returns more than one row

I have a query
SELECT id_anything FROM table1 JOIN table2 USING (id_tables)
Now, i have a situation which is:
If that join returns two rows from table2 i want to show the id_anything from table1 (1 row only)
and if the join from table2 returns 1 row, i want to show id_anything from table2.
Ps: id_anything from table 2 returns different values
Example data:
table1
id_tables | id_anything
1 | 1
table2
id_tables | id_anything
1 | 10
1 | 100
Return expected: 1
First, get the value you may want to return and the basis for deciding which to return together into one row.
SELECT table1.id_tables, table1.id_anything AS table1_id, MIN(table2.id_anything) AS table2_id, COUNT(*)
FROM table1 JOIN table2 USING (id_tables)
GROUP BY table1.id_tables, table1.id_anything
The aggregate function you use doesn't really matter since you'll only be using the value if there is only one.
You can then pick the relevant value:
WITH join_summary AS (
SELECT table1.id_tables, table1.id_anything AS table1_id, MIN(table2.id_anything) AS table2_id, COUNT(*) AS match_count
FROM table1 JOIN table2 USING (id_tables)
GROUP BY table1.id_tables, table1.id_anything
)
SELECT id_tables, CASE WHEN (match_count > 1) THEN table1_id ELSE table2_id END AS id_anything
FROM join_summary