Здесь у нас есть таблица из 34 строк.
DECLARE @x TABLE (TotalStd INT)
INSERT @x (TotalStd) VALUES (16), (21), (23), (25), (26), (28), (29), (29), (30), (30), (31), (32), (32), (32), (32), (33), (34),
(34), (35), (35), (35), (36), (38), (40), (41), (43), (43), (44), (45), (46), (47), (48), (48), (57)
SELECT '@x', TotalStd FROM @x ORDER BY TotalStd
Мы хотим разделить на квартили. Если мы используем NTILE
, размеры сегмента будут примерно одинаковыми (от 8 до 9 рядов в каждом), но связи нарушаются произвольно:
SELECT '@x with NTILE', TotalStd, NTILE(4) OVER (ORDER BY TotalStd) quantile FROM @x
Посмотрите, как 30 появляется дважды: один раз в квантиле 1 и один раз в квантиле 2. Аналогично, 43 появляется в квантилях 3 и 4.
То, что я должен найти, - это 10 предметов в квантиле 1, 8 в квантиле 2, 7 в квантиле 3 и 9 в квантиле 4 (т.е. не идеальное 9-8-9-8, но такое разделение невозможно, если нам не разрешают произвольно разрывать связи). Я могу сделать это, используя NTILE
для определения точек отсечения во временной таблице:
DECLARE @cutoffs TABLE (quantile INT, min_value INT, max_value INT)
INSERT @cutoffs (quantile, min_value)
SELECT y.quantile, MIN(y.TotalStd)
FROM (SELECT TotalStd, NTILE(4) OVER (ORDER BY TotalStd) AS quantile FROM @x) y
GROUP BY y.quantile
-- The max values are the minimum values of the next quintiles
UPDATE c1 SET c1.max_value = ISNULL(C2.min_value, (SELECT MAX(TotalStd) + 1 FROM @x))
FROM @cutoffs c1 LEFT OUTER JOIN @cutoffs c2 ON c2.quantile - 1 = c1.quantile
SELECT '@cutoffs', * FROM @cutoffs
Мы будем использовать граничные значения в таблице @cutoffs
для создания финальной таблицы:
SELECT x.TotalStd, c.quantile FROM @x x
INNER JOIN @cutoffs c ON x.TotalStd >= c.min_value AND x.TotalStd < c.max_value