【发布时间】:2021-08-19 11:41:04
【问题描述】:
我有一个表,其结构或多或少(我已针对问题对其进行了简化)如下所示:
| id (P.K.) | creation_ts | some_field |
|---|---|---|
| 1 | 2021-08-19 | foo |
| 2 | 2021-08-18 | foo |
| 3 | 2021-08-17 | foo |
| 4 | NULL | bar |
| 5 | 2021-01-01 | bar |
| 6 | 2021-01-02 | bar |
我正在尝试构建一个查询来显示一个计算列,该列每行具有相同的 "some_field" 值(呃...如果可以的话,按 "some_field" 的值分组?)会添加一个额外的is_newest 列显示哪一行是最新的。
| id (P.K.) | creation_ts | some_field | is_newest |
|---|---|---|---|
| 1 | 2021-08-19 | foo | TRUE |
| 2 | 2021-08-18 | foo | FALSE |
| 3 | 2021-08-17 | foo | FALSE |
| 4 | NULL | bar | FALSE |
| 5 | 2021-01-01 | bar | FALSE |
| 6 | 2021-01-02 | bar | TRUE |
这样做的目的是创建一个 SqlAlchemy Hybrid property,以便我们可以快速查询诸如 “get me the latest record WHERE some_field = 'foo'”之类的内容
我想这一定是某种CASE 声明(至少这是我从this other S.O. answer 收集到的,看起来很有希望)但我能想到的最好的东西是这样的:
@is_newest.expression
def is_newest(cls):
subq = sa.sql.exists().where(
sa.and_(
cls.id != cls.id,
cls.some_field == cls.some_field,
# Dirty trick: If there aren't newer records than this one,
# then this must be the newest
cls.creation_ts > cls.creation_ts,
)
)
return sa.case([(subq, False)], else_=True).label("is_newest")
但不是:这对我来说似乎很错误(而且它不起作用,因为某些单元测试失败了),因为它会产生类似...的查询
SELECT table.id, table.creation_ts, table.some_field
FROM table WHERE
CASE WHEN (EXISTS (
SELECT * FROM table WHERE
table.id != table.id
AND table.some_field = table.some_field
AND table.creation_ts > table.creation_ts)
) THEN False
ELSE True END IS true
AND table.some_field = 'foo'
...看起来不太对劲。虽然说实话,我不太确定“看起来不错”(我是 Postgres 的新手)
任何提示将不胜感激。提前谢谢你
【问题讨论】:
标签: python postgresql sqlalchemy subquery calculated-columns