left join 2 tables not working - left-join
I have 2 tables:
Table1: 'op_ats'
| ID1 | numero |id_cofre | id_chave | estadoAT
| 1 | 111 | 1 | 3 | 1
| 2 | 222 | 3 | 3 | 2
| 3 | 333 | 1 | 4 | 2
| 4 | 444 | 1 | 2 | 3
Table_2: 'op_ats_cofres_chaves'
| ID2 | num_chave |
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | D |
| 5 | E |
I have this SQL:
SELECT chaves.*, ats.numero numAT, ats.estadoAT
FROM op_ats_cofres_chaves chaves
LEFT JOIN op_ats ats ON ats.id_chave_cofre = chaves.id AND ats.id_cofre = 1
With this I get the following result:
| ID2 | num_chave | numAT | estadoAT |
| 1 | A | 444 | 3 |
| 2 | B | NULL | NULL |
| 3 | C | 111 | 1 |
| 4 | D | 333 | 2 |
| 5 | E | NULL | NULL |
Now the problem is that I want to filter the rows that are in Table1 but only that have the column 'estadoAT' with values 1 and 2. I've tried to add the line
WHERE op_ats.estadoAT = 1 OR op_ats.estadoAT = 2
But this makes the following result:
| ID2 | num_chave | numAT | estadoAT |
| 1 | A | 444 | 3 |
| 3 | C | 111 | 1 |
| 4 | D | 333 | 2 |
Resuming...
My intention is to get ALL rows in the Table2 and join the Table1 rows that have the 'id_cofre = 1' and '(estadoAT = 1 OR estadoAT = 2)'.
Any help is appreciated.
You have to move condition to JOIN clause instead of WHERE.
SELECT chaves.*, ats.numero numAT, ats.estadoAT
FROM op_ats_cofres_chaves chaves
LEFT JOIN op_ats ats ON ats.id_chave_cofre = chaves.id AND ats.id_cofre = 1
AND op_ats.estadoAT = 1 OR op_ats.estadoAT = 2;
Related
Replace null by negative id number in not consecutive rows in hive
I have this table in my database: | id | desc | |-------------| | 1 | A | | 2 | B | | NULL | C | | 3 | D | | NULL | D | | NULL | E | | 4 | F | --------------- And I want to transform this table into a table that replace nulls by consecutive negative ids: | id | desc | |-------------| | 1 | A | | 2 | B | | -1 | C | | 3 | D | | -2 | D | | -3 | E | | 4 | F | --------------- Anyone knows how can I do this in hive?
Below approach works select coalesce(id,concat('-',ROW_NUMBER() OVER (partition by id))) as id,desc from database_name.table_name;
postgresql : self join with array
My question is about forming Postgres SQL query for below use case Approach#1 I have a table like below where I generate the same uuid across different types(a,b,c,d) like mapping different types. +----+------+-------------+ | id | type | master_guid | +----+------+-------------+ | 1 | a | uuid-1 | | 2 | a | uuid-2 | | 3 | a | uuid-3 | | 4 | a | uuid-4 | | 5 | a | uuid-5 | | 6 | b | uuid-1 | | 7 | b | uuid-2 | | 8 | b | uuid-3 | | 9 | b | uuid-6 | | 10 | c | uuid-1 | | 11 | c | uuid-2 | | 12 | c | uuid-3 | | 13 | c | uuid-6 | | 14 | c | uuid-7 | | 15 | d | uuid-6 | | 16 | d | uuid-2 | +----+------+-------------+ Approach#2 I have a created two tables for id to type and then id to master_guid, like below table1: +----+------+ | id | type | +----+------+ | 1 | a | | 2 | a | | 3 | a | | 4 | a | | 5 | a | | 6 | b | | 7 | b | | 8 | b | | 9 | b | | 10 | c | | 11 | c | | 12 | c | | 13 | c | | 14 | c | | 15 | d | | 16 | d | +----+------+ table2 +----+-------------+ | id | master_guid | +----+-------------+ | 1 | uuid-1 | | 2 | uuid-2 | | 3 | uuid-3 | | 4 | uuid-4 | | 5 | uuid-5 | | 6 | uuid-1 | | 7 | uuid-2 | | 8 | uuid-3 | | 9 | uuid-6 | | 10 | uuid-1 | | 11 | uuid-2 | | 12 | uuid-3 | | 13 | uuid-6 | | 14 | uuid-7 | | 15 | uuid-6 | | 16 | uuid-2 | +----+-------------+ I want to get output like below with both approaches: +----+------+--------+------------+ | id | type | uuid | mapped_ids | +----+------+--------+------------+ | 1 | a | uuid-1 | [6,10] | | 2 | a | uuid-2 | [7,11] | | 3 | a | uuid-3 | [8,12] | | 4 | a | uuid-4 | null | | 5 | a | uuid-5 | null | +----+------+--------+------------+ I have tried self-joins with array_agg on ids and grouping based on uuid but not able to get the desired output. Use below query to populate data: Approach#1 insert into table1 values (1,'a','uuid-1'), (2,'a','uuid-2'), (3,'a','uuid-3'), (4,'a','uuid-4'), (5,'a','uuid-5'), (6,'b','uuid-1'), (7,'b','uuid-2'), (8,'b','uuid-3'), (9,'b','uuid-6'), (10,'c','uuid-1'), (11,'c','uuid-2'), (12,'c','uuid-3'), (13,'c','uuid-6'), (14,'c','uuid-7'), (15,'d','uuid-6'), (16,'d','uuid-2') Approach#2 insert into table1 values (1,'a'), (2,'a'), (3,'a'), (4,'a'), (5,'a'), (6,'b'), (7,'b'), (8,'b'), (9,'b'), (10,'c'), (11,'c'), (12,'c'), (13,'c'), (14,'c'), (15,'d'), (16,'d') insert into table2 values (1,'uuid-1'), (2,'uuid-2'), (3,'uuid-3'), (4,'uuid-4'), (5,'uuid-5'), (6,'uuid-1'), (7,'uuid-2'), (8,'uuid-3'), (9,'uuid-6'), (10,'uuid-1'), (11,'uuid-2'), (12,'uuid-3'), (13,'uuid-6'), (14,'uuid-7'), (15,'uuid-6'), (16,'uuid-2')
demo: db<>fiddle Using window function ARRAY_AGG allows you to aggregate your ids per groups (in your case the groups are your uuids) SELECT id, type, master_guid as uuid, array_agg(id) OVER (PARTITION BY master_guid) as mapped_ids FROM table1 ORDER BY id Result: | id | type | uuid | mapped_ids | |----|------|--------|------------| | 1 | a | uuid-1 | 10,6,1 | | 2 | a | uuid-2 | 16,2,7,11 | | 3 | a | uuid-3 | 8,3,12 | | 4 | a | uuid-4 | 4 | | 5 | a | uuid-5 | 5 | | 6 | b | uuid-1 | 10,6,1 | | 7 | b | uuid-2 | 16,2,7,11 | | 8 | b | uuid-3 | 8,3,12 | | 9 | b | uuid-6 | 15,13,9 | | 10 | c | uuid-1 | 10,6,1 | | 11 | c | uuid-2 | 16,2,7,11 | | 12 | c | uuid-3 | 8,3,12 | | 13 | c | uuid-6 | 15,13,9 | | 14 | c | uuid-7 | 14 | | 15 | d | uuid-6 | 15,13,9 | | 16 | d | uuid-2 | 16,2,7,11 | These arrays currently contain also the id of the current row (mapped_ids of id = 1 contains the 1). This can be corrected by remove this element with array_remove: SELECT id, type, master_guid as uuid, array_remove(array_agg(id) OVER (PARTITION BY master_guid), id) as mapped_ids FROM table1 ORDER BY id Result: | id | type | uuid | mapped_ids | |----|------|--------|------------| | 1 | a | uuid-1 | 10,6 | | 2 | a | uuid-2 | 16,7,11 | | 3 | a | uuid-3 | 8,12 | | 4 | a | uuid-4 | | | 5 | a | uuid-5 | | | 6 | b | uuid-1 | 10,1 | | 7 | b | uuid-2 | 16,2,11 | | 8 | b | uuid-3 | 3,12 | | 9 | b | uuid-6 | 15,13 | | 10 | c | uuid-1 | 6,1 | | 11 | c | uuid-2 | 16,2,7 | | 12 | c | uuid-3 | 8,3 | | 13 | c | uuid-6 | 15,9 | | 14 | c | uuid-7 | | | 15 | d | uuid-6 | 13,9 | | 16 | d | uuid-2 | 2,7,11 | Now for example id=4 contains an empty array instead of a NULL value. This can be achieved by using the NULLIF function. This gives NULL if both parameters are equal, else it gives out the first parameter. SELECT id, type, master_guid as uuid, NULLIF( array_remove(array_agg(id) OVER (PARTITION BY master_guid), id), '{}'::int[] ) as mapped_ids FROM table1 ORDER BY id Result: | id | type | uuid | mapped_ids | |----|------|--------|------------| | 1 | a | uuid-1 | 10,6 | | 2 | a | uuid-2 | 16,7,11 | | 3 | a | uuid-3 | 8,12 | | 4 | a | uuid-4 | (null) | | 5 | a | uuid-5 | (null) | | 6 | b | uuid-1 | 10,1 | | 7 | b | uuid-2 | 16,2,11 | | 8 | b | uuid-3 | 3,12 | | 9 | b | uuid-6 | 15,13 | | 10 | c | uuid-1 | 6,1 | | 11 | c | uuid-2 | 16,2,7 | | 12 | c | uuid-3 | 8,3 | | 13 | c | uuid-6 | 15,9 | | 14 | c | uuid-7 | (null) | | 15 | d | uuid-6 | 13,9 | | 16 | d | uuid-2 | 2,7,11 |
Try this: select t1.id, t1.type, t1.master_guid, array_agg (distinct t2.id) from table1 t1 left join table1 t2 on t1.master_guid = t2.master_guid and t1.id != t2.id group by t1.id, t1.type, t1.master_guid I don't come up with exactly the same results you listed, but I thought it was close enought that maybe there was a mistaken expectation on your side or only a small error on mine... either way, a potential starting point. -- EDIT -- For approach #2, I think you just need to add an inner join to Table2 to get the GUID: select t1.id, t1.type, t2.master_guid, array_agg (t2a.id) from table1 t1 join table2 t2 on t1.id = t2.id left join table2 t2a on t2.master_guid = t2a.master_guid and t2a.id != t1.id where t1.type = 'a' group by t1.id, t1.type, t2.master_guid
count continuously postgresql data
i need help with counting some data this what i want | user_id | action_id | count | ------------------------------------- | 1 | 1 | 1 | | 2 | 2 | 1 | | 3 | 2 | 2 | | 4 | 3 | 1 | | 5 | 3 | 2 | | 6 | 3 | 3 | | 7 | 4 | 1 | | 8 | 5 | 1 | | 9 | 5 | 2 | | 10 | 6 | 1 | this is what i have | user_id | action_id | count | ------------------------------- | 1 | 1 | 1 | | 2 | 2 | 1 | | 3 | 2 | 1 | | 4 | 3 | 1 | | 5 | 3 | 1 | | 6 | 3 | 1 | | 7 | 4 | 1 | | 8 | 5 | 1 | | 9 | 5 | 1 | | 10 | 6 | 1 | i really need it for create some research about second action from users how do i do it? thank you
Using ROW_NUMBER should work here: SELECT user_id, action_id, ROW_NUMBER() OVER (PARTITION BY action_id ORDER BY user_id) count FROM yourTable ORDER BY user_id; Demo
SQL query help: Calculate max of previous rows in the same query
I want to find for each row(where B = C = D = 1), the max of A among its previous rows(where B = C = D = 1) excluding its row after its ordered in chronological order. Data in table looks like this: +-------+-----+-----+-----+------+------+ |Grp id | B | C | D | A | time | +-------+---- +-----+-----+------+------+ | 111 | 1 | 0 | 0 | 52 | t | | 111 | 1 | 1 | 1 | 33 | t+1 | | 111 | 0 | 1 | 0 | 34 | t+2 | | 111 | 1 | 1 | 1 | 22 | t+3 | | 111 | 0 | 0 | 0 | 12 | t+4 | | 222 | 1 | 1 | 1 | 16 | t | | 222 | 1 | 0 | 0 | 18 | t2+1 | | 222 | 1 | 1 | 0 | 13 | t2+2 | | 222 | 1 | 1 | 1 | 12 | t2+3 | | 222 | 1 | 1 | 1 | 09 | t2+4 | | 222 | 1 | 1 | 1 | 22 | t2+5 | | 222 | 1 | 1 | 1 | 19 | t2+6 | +-------+-----+-----+-----+------+------+ Above table is resultant of below query. Its obtained after left joins as below. Joins are necessary according to my project requirement. SELECT Grp id, B, C, D, A, time, xxx FROM "DCR" dcr LEFT JOIN "DCM" dcm ON "Id" = dcm."DCRID" LEFT JOIN "DC" dc ON dc."Id" = dcm."DCID" ORDER BY dcr."time" Result column needs to be evaluated based on formula I mentioned above. It needs to be calculated in same pass as we need to consider only its previous rows. Above xxx needs to be replaced by a subquery/statement to obtain the result. And the result table should look like this: +-------+-----+-----+-----+------+------+------+ |Grp id | B | C | D | A | time |Result| +-------+---- +-----+-----+------+------+------+ | 111 | 1 | 0 | 0 | 52 | t | - | | 111 | 1 | 1 | 1 | 33 | t+1 | - | | 111 | 1 | 1 | 1 | 34 | t+2 | 33 | | 111 | 1 | 1 | 1 | 22 | t+3 | 34 | | 111 | 0 | 0 | 0 | 12 | t+4 | - | | 222 | 1 | 1 | 1 | 16 | t | - | | 222 | 1 | 0 | 0 | 18 | t2+1 | - | | 222 | 1 | 1 | 0 | 13 | t2+2 | - | | 222 | 1 | 1 | 1 | 12 | t2+3 | 16 | | 222 | 1 | 1 | 1 | 09 | t2+4 | 16 | | 222 | 1 | 1 | 1 | 22 | t2+5 | 16 | | 222 | 1 | 1 | 1 | 19 | t2+6 | 22 | +-------+-----+-----+-----+------+------+------+
The column could be computed with a window function: CASE WHEN b = 1 AND c = 1 AND d = 1 THEN max(a) FILTER (WHERE b = 1 AND c = 1 AND d = 1) OVER (PARTITION BY "grp id" ORDER BY time ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) ELSE NULL END I didn't test it.
Comparing Subqueries
I have two subqueries. Here is the output of subquery A.... id | date_lat_lng | stat_total | rnum -------+--------------------+------------+------ 16820 | 2016_10_05_10_3802 | 9 | 2 15701 | 2016_10_05_10_3802 | 9 | 3 16821 | 2016_10_05_11_3802 | 16 | 2 17861 | 2016_10_05_11_3802 | 16 | 3 16840 | 2016_10_05_12_3683 | 42 | 2 17831 | 2016_10_05_12_3767 | 0 | 2 17862 | 2016_10_05_12_3802 | 11 | 2 17888 | 2016_10_05_13_3683 | 35 | 2 17833 | 2016_10_05_13_3767 | 24 | 2 16823 | 2016_10_05_13_3802 | 24 | 2 and subquery B, in which date_lat_lng and stat_total has commonality with subquery A, but id does not. id | date_lat_lng | stat_total | rnum -------+--------------------+------------+------ 17860 | 2016_10_05_10_3802 | 9 | 1 15702 | 2016_10_05_11_3802 | 16 | 1 17887 | 2016_10_05_12_3683 | 42 | 1 15630 | 2016_10_05_12_3767 | 20 | 1 16822 | 2016_10_05_12_3802 | 20 | 1 16841 | 2016_10_05_13_3683 | 35 | 1 15632 | 2016_10_05_13_3767 | 23 | 1 17863 | 2016_10_05_13_3802 | 3 | 1 16842 | 2016_10_05_14_3683 | 32 | 1 15633 | 2016_10_05_14_3767 | 12 | 1 Both subquery A and B pull data from the same table. I want to delete the rows in that table that share the same ID as subquery A but only where date_lat_lng and stat_total have a shared match in subquery B. Effectively I need: DELETE FROM table WHERE id IN (SELECT id FROM (subqueryA) WHERE subqueryA.date_lat_lng=subqueryB.date_lat_lng AND subqueryA.stat_total=subqueryB.stat_total) Except I'm not sure where to place subquery B, or if I need an entirely different structure.
Something like this, DELETE FROM table WHERE id IN ( SELECT DISTINCT id FROM subqueryA JOIN subqueryB USING (id,date_lat_lng,stat_total) )