简体   繁体   中英

How to get only the recent joined pairs?

I've got two tables, where the second is connected to the first with multiple entries ( 1:n ).

The first table has entries for an id_something (another table, but not important for now) and for every day date_day .

+-----------+
| Table ONE |
+----+------+-------+----------+----------+
| id | id_something | date_day | created  |
+----+--------------+----------+----------+
|  1 |          666 | 2019-1-1 | 2019-1-1 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |
|  3 |          123 | 2019-1-1 | 2019-1-1 |
+----+--------------+----------+----------+

The second table is connected to this id and contain key-value-pairs.

+-----------+
| Table TWO |
+--------+--+--+-----+
| id_one | foo | bar |
+--------+-----+-----+
|      1 |   1 |  20 |
|      1 |   2 |  21 |
|      2 |   1 |  30 |
|      2 |   2 |  31 |
|      2 |   3 |  32 |
|      3 |   1 |  10 |
+--------+-----+-----+

I want to query for all possible connections, so simple, it's a JOIN:

SELECT *
FROM one
LEFT JOIN two
ON two.id_one = one.id;

+----+--------------+----------+----------+--------+-----+-----+
| id | id_something | date_day | created  | id_one | foo | bar |
+----+--------------+----------+----------+--------+-----+-----+
|  1 |          666 | 2019-1-1 | 2019-1-1 |      1 |   1 |  20 |
|  1 |          666 | 2019-1-1 | 2019-1-1 |      1 |   2 |  21 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   1 |  30 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   2 |  31 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   3 |  32 |
|  3 |          123 | 2019-1-1 | 2019-1-1 |      3 |   1 |  10 |
+----+--------------+----------+----------+--------+-----+-----+

Now as you see, I also have a created field. The id_something in conjunction with date_day could be the same - but I only want to have the most recent ( created DESC ) pairs with the second table.

So in this case, the query should return:

+----+--------------+----------+----------+--------+-----+-----+
| id | id_something | date_day | created  | id_one | foo | bar |
+----+--------------+----------+----------+--------+-----+-----+
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   1 |  30 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   2 |  31 |
|  2 |          666 | 2019-1-1 | 2019-7-7 |      2 |   3 |  32 |
|  3 |          123 | 2019-1-1 | 2019-1-1 |      3 |   1 |  10 |
+----+--------------+----------+----------+--------+-----+-----+

But I can't get it to work... I tried to use DISTINCT or even a sub-query and a case construct, but it either doesn't work or is very imperformant. A group-by would also not return every joined pair, but just one single line for every id out of table one.

What am I missing to achieve my wished result?

(if no Oracle-specific synthax would be used, that would be a bonus.)

You can use analytic functions:

SELECT *
FROM (SELECT o.* ROW_NUMBER() OVER (PARTITION BY id ORDER BY created DESC) as seqnum
      FROM one o
     ) o LEFT JOIN
     two t
     ON t.id_one = o.id
WHERE o.seqnum = 1;

use row_number() take the most recent id_something and then use join

select a.*,b.* from     
(
select *,
row_number()over(partition by id_something order by created desc) rn  from one
) a join two b ON b.id_one = a.id;
 where rn=1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM