我正在使用 POSTGRESQL,但我找不到解决问题的方法。我有一个名为 Foobar 的模型。它的一些属性是:
FOOBAR
check_in:datetime
qr_code:string
city_id:integer
在这个表中有很多冗余(qr_code 不是唯一的)但这不是我现在的问题。我想要得到的是具有相同 qr_code 并且在一个众所周知的城市组中的 foobars,这些 foobars 在不同的时间签到。 我通过查询得到了这个:
SELECT * FROM foobar AS a
WHERE a.city_id = 1
AND EXISTS (
SELECT * FROM foobar AS b
WHERE a.check_in < b.check_in
AND a.qr_code = b.qr_code
AND b.city_id = 2
AND EXISTS (
SELECT * FROM foobar as c
WHERE b.check_in < c.check_in
AND c.qr_code = b.qr_code
AND c.city_id = 3
AND EXISTS(...)
)
)
其中“...”表示更多查询,以获取更多具有相同二维码、不同入住日期和那些知名城市的人。
我的问题是我想通过 qr_code 对其进行分组,并且我想像这样显示每个 qr_code 的 check_in 字段:
2015-11-11 14:14:14 => [2015-11-11 14:14:14, 2015-11-11 16:16:16, 2015-11-11 17:18:20] (这适用于每个不同的 qr_code)
其中左侧的数据是该二维码的“较小”日期,右侧是该二维码的所有其他日期,包括第一个。 这可能只与 sql 查询有关吗?我问这个是因为我实际上是在用 Rails 做这个应用程序,而且我知道我可以用 ruby 的数组方法做一个不同的方法(一个解决方案也会很受欢迎)
最佳答案
你可以用 recursive CTE 来解决这个问题- 如果我正确解释了你的问题:
假设您有一个给定的城市列表,必须按相同的 qr_code
顺序访问这些城市。你的文字没有这么说,但你的查询表明了很多。
WITH RECURSIVE
c AS (SELECT '{1,2,3}'::int[] AS cities) -- your list of city_id's here
, route AS (
SELECT f.check_in, f.qr_code, 2 AS idx
FROM foobar f
JOIN c ON f.city_id = c.cities[1]
UNION ALL
SELECT f.check_in, f.qr_code, r.idx + 1
FROM route r
JOIN foobar f USING (qr_code)
JOIN c ON f.city_id = c.cities[r.idx]
WHERE r.check_in < f.check_in
)
SELECT qr_code, array_agg(check_in) AS check_in_list
FROM (
SELECT *
FROM route
ORDER BY qr_code, idx -- or check_in
) sub
HAVING count(*) = (SELECT array_length(cities) FROM c);
GROUP BY 1;
在第一个(非递归)CTE c
中将列表作为数组提供。
在递归部分,从第一个城市中的任何行开始,沿着数组移动直到最后一个元素。
在最后的 SELECT
中,按顺序聚合您的 check_in
列。只返回访问过所有数组城市的qr_code
。
类似的:
关于sql - 如何按多个行值分组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31601902/