【问题标题】:Returning last row in left outer join on multiple conditions在多个条件下返回左外连接中的最后一行
【发布时间】:2019-07-30 22:23:13
【问题描述】:

我正在尝试查询两个表。我在下面制作了示例表:

---------------TABLE1 (t1)------------
| id  |type |    date    |
|  1  |  A  | 2018-01-01 |
|  2  |  C  | 2018-02-01 |
|  3  |  C  | 2018-03-01 |
|  4  |  C  | 2018-04-01 |
|  5  |  A  | 2018-01-01 |
|  6  |  C  | 2018-02-01 |
|  7  |  C  | 2018-03-01 |
|  8  |  B  | 2018-04-01 |

---------------TABLE2 (t2)------------
| id  |    date    |amount|  created   |
|  1  | 2018-01-01 |  100 | 2017-10-01 |
|  1  | 2018-01-01 |  700 | 2017-12-01 |
|  1  | 2018-03-01 |  300 | 2018-01-01 |
|  2  | 2018-02-01 |  500 | 2017-12-01 |
|  2  | 2018-02-01 |   50 | 2017-10-01 |
|  3  | 2018-03-01 |  750 | 2018-02-01 |
|  3  | 2018-03-01 | 1000 | 2018-03-01 |
|  4  | 2018-04-01 |  200 | 2018-03-01 |
|  5  | 2018-04-01 |  300 | 2018-02-01 |

我想要以下:

---------------TABLE3------------
| id  |type |    date    |amount|  created   |
|  2  |  C  | 2018-02-01 |  500 | 2017-12-01 |
|  3  |  C  | 2018-03-01 | 1000 | 2018-03-01 |
|  4  |  C  | 2018-04-01 |  200 | 2018-03-01 |
|  6  |  C  | 2018-02-01 | NULL |    NULL    |
|  7  |  C  | 2018-03-01 | NULL |    NULL    |

t1.id = t2.idt1.date=t2.datet1.type = 'C' 的条件下,我想要一个左连接(我认为在Postgres 中这是默认的外连接)。

我的查询很容易完成,但偶尔会在t2 上收到多个匹配项。在这种情况下,我只想从t2 中获取最新created 日期的行。

最后,我希望表格的行数与以下内容相同: SELECT COUNT(*) FROM t1 WHERE type = 'C'

我检查了网站上的多个其他问题,但在多个条件下无法弄清楚如何做到这一点。

【问题讨论】:

  • 请显示您当前正在按照您的描述执行的 sql。然后我可以修改它来做你想做的事

标签: sql postgresql


【解决方案1】:

demo:db<>fiddle

你可以先用DISTINCT ON过滤t2:

SELECT DISTINCT ON (id)
    *
FROM
    t2
ORDER BY id, date DESC

之后你可以加入这个:

SELECT *
FROM t1
LEFT JOIN (
   -- subquery here
) t2
ON t1.id = t2.date

DISTINCT ON 给出有序组的第一条记录。您的群组是id。如果您按日期降序排列id 组,则将最近的记录移到顶部。

之后,您可以在WHERE 子句中按type 进行过滤。

【讨论】:

  • 这正是我所需要的。从来不知道DISTINCT ON 函数...干杯!
【解决方案2】:

Postgres 有一个非常好的扩展名为distinct on。这使得表达你的逻辑和每个id返回一行变得非常简单:

select distinct on (t1.id), t1.*, t2.amount, t2.created
from table1 t1 left join
     table2 t2
     on t1.id = t2.id and t1.date = t2.date
where t1.type = 'C'
order by t1.id, t2.created desc

【讨论】:

    猜你喜欢
    • 2013-04-19
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    • 1970-01-01
    • 2010-11-11
    • 2020-01-08
    • 2014-01-27
    • 2017-09-28
    相关资源
    最近更新 更多