我正在使用类似于以下的表格:
周 | 时间 | 人 | 方向 | 距离 |
---|---|---|---|---|
1 | 12:00 | A | 27 | 4 |
1 | 12:00 | A | 27 | 6 |
1 | 12:00 | A | 27 | 8 |
1 | 12:00 | 乙 | 20 | 2 |
1 | 12:00 | 乙 | 20 | 5 |
1 | 12:00 | 乙 | 20 | 7 |
1 | 12:00 | C | 17 | 3 |
1 | 12:00 | C | 17 | 4 |
1 | 12:00 | C | 17 | 6 |
1 | 1:00 | A | 3 | 9 |
1 | 1:00 | A | 3 | 7 |
1 | 1:00 | A | 3 | 5 |
1 | 1:00 | 乙 | 6 | 3 |
1 | 1:00 | 乙 | 6 | 4 |
1 | 1:00 | 乙 | 6 | 8 |
1 | 1:00 | C | 12 | 10 |
1 | 1:00 | C | 12 | 9 |
1 | 1:00 | C | 12 | 14 |
如您所见,在
Time
的每个值内,每个 Person
都有多个观察值。每个人在给定时间的所有观察中都有相同的Direction
值,但Distance
的值不同。对于Time
的每个值,我只想为最大化Distance
的人选择具有最小Direction
的观察。
我还想为具有第二高
Direction
值和最小值Distance.
的人创建列
所以对于每个时间值,我只会返回一个观察结果。这是我要返回的内容:
周 | 时间 | max_direction_person | max_person_min_distance | second_max_direction_person | second_max_person_min_distance |
---|---|---|---|---|---|
1 | 12:00 | A | 4 | 乙 | 2 |
1 | 1:00 | C | 9 | 乙 | 3 |
这怎么可能?我试过按子查询分组,但没有成功。
您可以为此使用窗口函数。
DENSE_RANK
将识别每组 Person
行的顺序,然后 ROW_NUMBER
可以在这些集合中编号。
然后过滤到密集等级为 1 或 2 且行号为 1 的行,然后使用
MIN
或 MAX
简单地旋转它以获得每个 Time
的分组结果。
WITH Maxed AS (
SELECT *,
dr = DENSE_RANK() OVER (PARTITION BY Week, Time ORDER BY Direction DESC),
rn = ROW_NUMBER() OVER (PARTITION BY Week, Time, Direction, Person ORDER BY Distance ASC)
FROM Observation o
)
SELECT
Week,
Time,
max_direction_person = MIN(CASE WHEN dr = 1 THEN Person END),
max_person_min_distance = MIN(CASE WHEN dr = 1 AND rn = 1 THEN Distance END),
second_max_direction_person = MIN(CASE WHEN dr = 2 THEN Person END),
second_max_person_min_distance = MIN(CASE WHEN dr = 2 AND rn = 1 THEN Distance END)
FROM Maxed
WHERE dr >= 1 AND dr <= 2
AND rn = 1
GROUP BY
Week,
Time;
请注意,在
Direction
分区中添加 ROW_NUMBER
在技术上是不必要的,但是由于 DENSE_RANK
计算的现有排序,它会更有效。