SQL с учетом нескольких порогов, получить наибольшее значение ниже каждого порога - PullRequest
0 голосов
/ 01 февраля 2019

Мне дают несколько порогов (обычно 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 голосов
/ 01 февраля 2019

Я бы просто указал пороги в виде строк, чтобы их было легче объединить.

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.

...