我有一个PostgreSQL查询:
SELECT DISTINCT ON ("contract"."contract_id") "contract"."id"
FROM "contract_versions" "contract"
WHERE "contract"."client_id" = 1
GROUP BY "contract"."contract_id", "contract"."id"
ORDER BY "contract"."contract_id", "contract"."change_effective_date" DESC
我想添加一些内容,例如如果contract_id出现多次,则change_effective_date> = now()
数据集:
id | contract_id | client_id | change_effective_date
-----+-------------+-----------+-----------------------
100 | 10 | 1 | 2020-05-17 00:00:00
200 | 10 | 1 | 2020-05-16 00:00:00
300 | 10 | 1 | 2020-05-14 00:00:00
400 | 20 | 1 | 2020-05-17 00:00:00
500 | 30 | 1 | 2020-05-13 00:00:00
600 | 30 | 1 | 2020-05-14 00:00:00
预期结果:
id | contract_id | client_id | change_effective_date
-----+-------------+-----------+-----------------------
200 | 10 | 1 | 2020-05-16 00:00:00
400 | 20 | 1 | 2020-05-17 00:00:00
600 | 30 | 1 | 2020-05-14 00:00:00
如果contract_id的计数大于1,我希望行的change_effective_date小于或等于今天
我尝试使用:
SELECT DISTINCT ON ("contract"."contract_id") "contract"."id",
COUNT("contract"."contract_id") AS cnt
FROM "contract_versions" "contract"
WHERE "contract"."client_id" = 1 AND
CASE WHEN "cnt" > 1 THEN "contract"."change_effective_date" <= now() END
GROUP BY "contract"."contract_id", "contract"."id"
ORDER BY "contract"."contract_id", "contract"."change_effective_date" DESC
但抛出错误column "cnt" does not exist
谢谢
答案 0 :(得分:0)
您的查询中有2个问题:
错误:列“ contract.change_effective_date”必须出现在 GROUP BY子句或在聚合函数中使用
以下是可能的解决方案:
select * from contract_versions;
id | contract_id | client_id | change_effective_date
-----+-------------+-----------+-----------------------
100 | 10 | 1 | 2020-05-14 14:00:00
100 | 10 | 1 | 2020-05-14 14:00:00
100 | 10 | 1 | 2020-05-14 14:00:00
100 | 20 | 1 | 2020-05-16 09:00:00
(4 rows)
Null display is "NULL".
SELECT DISTINCT ON (contract_id) contract_id,
change_effective_date
FROM contract_versions contract
WHERE client_id = 1
GROUP BY contract_id, id, change_effective_date
ORDER BY contract_id, change_effective_date DESC;
contract_id | change_effective_date
-------------+-----------------------
10 | 2020-05-14 14:00:00
20 | 2020-05-16 09:00:00
(2 rows)
SELECT DISTINCT ON (contract_id) contract_id,
COUNT(contract_id) AS cnt,
change_effective_date
FROM contract_versions contract
WHERE client_id = 1
GROUP BY contract_id, id, change_effective_date
ORDER BY contract_id, change_effective_date DESC;
contract_id | cnt | change_effective_date
-------------+-----+-----------------------
10 | 3 | 2020-05-14 14:00:00
20 | 1 | 2020-05-16 09:00:00
(2 rows)
SELECT
contract_id,
CASE WHEN cnt > 1 THEN change_effective_date <= now()
END
FROM
(
SELECT DISTINCT ON (contract_id) contract_id,
COUNT(contract_id) AS cnt,
change_effective_date
FROM contract_versions contract
WHERE client_id = 1
GROUP BY contract_id, id, change_effective_date
ORDER BY contract_id, change_effective_date DESC
) v;
contract_id | case
-------------+------
10 | t
20 | NULL
(2 rows)
答案 1 :(得分:0)
我从未见过let timeString = "5:36"
let timeStringArray = timeString.split(separator: ":")
let minutesInt = Int(timeStringArray[0]) ?? 0
let secondsInt = Int(timeStringArray[1]) ?? 0
let resultInt = minutesInt * 60 + secondsInt
print(resultInt)
与DISTINCT ON
结合使用。可以(首先进行聚合,然后从该聚合结果中选择行),但这不是您要执行的操作,也不是您想要的。您希望GROUP BY
的{{1}}子句应用的排名考虑当前日期。
ORDER BY
演示:https://dbfiddle.uk/?rdbms=postgres_12&fiddle=f709d18b23504dfaf9f586ace231be1d
答案 2 :(得分:0)
具有row_number()
窗口功能:
select t.id, t.contract_id, t.client_id, t.change_effective_date
from (
select *,
row_number() over (
partition by contract_id
order by (change_effective_date > now())::int, change_effective_date desc
) rn
from contract_versions
) t
where t.rn = 1
order by t.id
这个问题尚不清楚,因为如果client_id
的值仅属于一个contract_id
,则示例数据仅包含1个client_id
。
如果不是这种情况,则必须在上面的查询中进行更改:
partition by contract_id
收件人:
partition by contract_id, client_id
请参见demo。
结果:
| id | contract_id | client_id | change_effective_date |
| --- | ----------- | --------- | ------------------------ |
| 200 | 10 | 1 | 2020-05-16 00:00:00.000 |
| 400 | 20 | 1 | 2020-05-17 00:00:00.000 |
| 600 | 30 | 1 | 2020-05-14 00:00:00.000 |