【发布时间】:2018-09-28 07:00:12
【问题描述】:
我有一个像这样的数据集:
student_id date project_id
1 1/1/18 15
1 1/1/18 17
1 2/2/18 16
1 3/3/18 15
1 3/3/18 12
2 2/3/18 3
2 4/3/18 4
2 5/3/18 6
2 5/3/18 4
我想用他们所做的前两个项目和他们所做的最后一个项目的日期来查找学生 ID,
student_id project_id1st date1st project_id2nd date2nd projectlast datelast
1 15 1/1/18 17 1/1/18 12 3/3/18
2 3 2/3/18 4 4/3/18 4 5/3/18
首先我想在 pandas 中解决它,但得到了一些不好的结果。然后我尝试用 SQL 解决它。
WITH abc AS (
SELECT student_id, project_id, date,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY date) rn
FROM table
)
SELECT student_id,
SUM(CASE WHEN rn = 1 THEN abc.project_id END) as firstid,
SUM(CASE WHEN rn = 2 THEN abc.project_id END) as secondsid,
MIN(CASE WHEN rn = 1 THEN date END) as first,
MIN(CASE WHEN rn = 2 THEN date END) as second
FROM abc
GROUP BY 1;
我得到了很好的结果,但不知何故它使用ROW_NUMBER() 弄乱了数据集的顺序。例如,对于学生 1,rownumber 中值为 1 的 project_id 17,project_id 15 将成为第二个开始日期。
【问题讨论】:
-
我有填写你需要的
distinct on(...)postgresql.org/docs/current/static/sql-select.html#SQL-DISTINCT -
当您有相同的日期时,您的预期订单是多少?如果你想要
date,然后是project_id,你必须在order by子句中说明这一点。 -
@S-Man 在原始数据集中的顺序相同,但是当我使用
row_number()时,它搞砸了 -
您的问题是您没有指示正确顺序的列。在
row_number窗口框架中,您可以按日期下订单。但是当框架中有很多行时,结果是完全随机的。您必须告诉数据库如何处理同一帧中的行。你想接project_id吗?或者你需要一个时间戳而不是日期?没有“原始订单”这样的指标。这是永远无法保证的。所以你不能得到一个正确的答案。 -
select min(t.test), max(t.test), t.bez, min(x.test) from test t left join ( SELECT test, bez, ROW_NUMBER() OVER (PARTITION BY bez ORDER BY bez) rn FROM test) x on x.bez = t.bez and x.rn = 2 group by t.bez
标签: sql postgresql date