SQL具有多个阈值,在每个阈值以下获取最大值

时间:2019-02-01 08:23:11

标签: sql sql-server tsql greatest-n-per-group

我有多个阈值(通常为2,但是可能有所不同)。我想为每个阈值找到在每个类别中具有小于或等于阈值的最大值的行。

例如给定类别2和阈值5和10:

mytable:
category | val | data
---------+-----+---------
1        | 1   | 'foo'
1        | 3   | 'bar'
1        | 4   | 'baz'
2        | 2   | 'quz'
2        | 5   | 'wibble'
2        | 6   | 'wobble'
2        | 8   | 'ham'
2        | 12  | 'spam'
3        | 1   | 'eggs'

所以结果应该是:

category | val | data
---------+-----+---------
1        | 4   | 'baz'     \
2        | 5   | 'wibble'  | These are <= threshold 5
3        | 1   | 'eggs'    /
1        | 4   | 'baz'     \
2        | 8   | 'ham'     | These are <= threshold 10
3        | 1   | 'eggs'    /

注意:如果行是不同的,但不是必需的,也可以。

到目前为止,我只能提供1个阈值的查询(基本上是标准的每组最多一次的查询):

SELECT t1.category, t1.val, t1.data
FROM mytable t1
JOIN (
  SELECT category, MAX(val) AS val
  FROM mytable
  GROUP BY category
  WHERE val < @threshold
) AS t2
ON t1.category=t2.category AND t1.val=t2.val

如何处理多个阈值?

如果有关系,我将使用T-SQL。一般的SQL查询会很好,但不是必需的。

1 个答案:

答案 0 :(得分:3)

我只是将阈值指定为行,以便更轻松地加入。

DECLARE @t TABLE (category int, val int, data varchar(10));
INSERT INTO @t VALUES
(1, 1, 'foo'),
(1, 3, 'bar'),
(1, 4, 'baz'),
(2, 2, 'quz'),
(2, 5, 'wibble'),
(2, 6, 'wobble'),
(2, 8, 'ham'),
(2, 12, 'spam'),
(3, 1, 'eggs');

SELECT *
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY threshold, category ORDER BY val DESC) AS rn
    FROM (VALUES
        (5),
        (10)
    ) thresholds(threshold)
    JOIN @t AS t ON val <= threshold
) AS x
WHERE rn = 1
ORDER BY threshold, category

如果(VAULES ...)子句不可用,您可以简单地使用FROM (SELECT 5 AS threshold UNION ALL SELECT 10) thresholds