如何在一组中选择最小值使另一个值最大化?

问题描述 投票:0回答:1

我正在使用类似于以下的表格:

时间 方向 距离
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

这怎么可能?我试过按子查询分组,但没有成功。

sql sql-server tsql greatest-n-per-group row-number
1个回答
0
投票

您可以为此使用窗口函数。

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;

db<>小提琴

请注意,在

Direction
分区中添加
ROW_NUMBER
在技术上是不必要的,但是由于
DENSE_RANK
计算的现有排序,它会更有效。

© www.soinside.com 2019 - 2024. All rights reserved.