Сложная задача ранжирования TSQL
Я перепробовал множество разнообразных решений для ранжирования с объединениями, чтобы удовлетворить потребности, которые я хочу.
К сожалению, я не могу придумать правильный запрос, чтобы получить желаемый результат.
Я действительно ищу любую помощь, чтобы получить объяснение, которое помогло бы мне в будущем с такого рода задачами.
У меня есть следующая таблица CTE содержит набор значений данных:
type model price code
Shoes 1298 700,00 1
Shoes 1298 950,00 6
Shoes 1298 1050,00 4
Shoes 1321 970,00 2
Shoes 1750 1200,00 3
Shoes 1752 1150,00 5
Pants 1121 850,00 2
Pants 1121 850,00 4
Pants 1121 850,00 5
Pants 1232 350,00 8
Pants 1232 350,00 9
Pants 1232 400,00 7
Pants 1232 600,00 1
Pants 1233 600,00 3
Pants 1233 950,00 6
Pants 1233 970,00 12
Pants 1233 980,00 11
Pants 1260 350,00 10
Hats 1276 400,00 1
Hats 1288 400,00 6
Hats 1401 150,00 4
Hats 1408 270,00 5
Hats 1433 270,00 2
Hats 1434 290,00 3
Единая нумерация записей CTE должна выполняться следующим образом: сначала идут первые модели таблиц (Shoes, Pants and Hats), затем последние модели, затем - вторые модели в таблицах, предпоследние и т. Д. В случае исчерпания моделей определенного типа, нумеруйте только оставшиеся модели других типов.
Вот желаемый результат:
Id type model price code
1 Shoes 1298 700.0000 1
2 Pants 1232 600.0000 1
3 Hats 1276 400.0000 1
4 Shoes 1298 950.0000 6
5 Pants 1233 970.0000 12
6 Hats 1288 400.0000 6
7 Shoes 1321 970.0000 2
8 Pants 1121 850.0000 2
9 Hats 1433 270.0000 2
10 Shoes 1752 1150.0000 5
11 Pants 1233 980.0000 11
12 Hats 1408 270.0000 5
13 Shoes 1750 1200.0000 3
14 Pants 1233 600.0000 3
15 Hats 1434 290.0000 3
16 Shoes 1298 1050.0000 4
17 Pants 1260 350.0000 10
18 Hats 1401 150.0000 4
19 Pants 1121 850.0000 4
20 Pants 1232 350.0000 9
21 Pants 1121 850.0000 5
22 Pants 1232 350.0000 8
23 Pants 1233 950.0000 6
24 Pants 1232 400.0000 7
Я обновил желаемый результат (добавлен код столбца), чтобы лучше понять идею сортировки. Это должно быть выполнено с перемежением с первыми закодированными номерами (т. Е. С наименьшим кодом) типов идет первым, затем последние кодированные номера (т. Е. С наивысшим кодом) типов идут вторым, затем сначала кодируется, кто слева, идет первым, а затем последний кодируется, кто слева и так далее.
3 ответа
Вы хотите, чтобы значение чередовалось. Вот как вы можете сделать это:
with cte as ( . . . )
select row_number() over (order by seqnum, charindex(type, 'ShoesPantsHats')) as id,
t.*
from (select cte.*,
row_number() over (partition by type order by (select NULL)) as seqnum
from cte
) t
order by seqnum,
charindex(type, 'ShoesPantsHats');
Обратите внимание order by
пункт для row_number()
, Таблицы SQL по своей природе неупорядочены, и если вы заботитесь о порядке следования результатов внутри каждого типа, поместите туда соответствующую логику.
Я не могу понять порядок за сценой, потому что результирующий набор не упорядочен ни по модели, ни по коду, но вот идея, и вы можете поиграть с порядками в CTE:
WITH cte1 AS ( SELECT * ,
ROW_NUMBER() OVER (PARTITION BY type ORDER BY model, code) rn1
FROM @t),
cte2 AS ( SELECT * ,
ROW_NUMBER() OVER (PARTITION BY rn1 ORDER BY
CASE type WHEN 'Shoes' THEN 1
WHEN 'Pants' THEN 2
WHEN 'Hats' THEN 3 END) rn2
FROM cte1 )
SELECT * ,
ROW_NUMBER() OVER (ORDER BY rn1, rn2) rn
FROM cte2
Выход:
type model price code rn1 rn2 rn
Shoes 1298 700.00 1 1 1 1
Pants 1121 850.00 2 1 2 2
Hats 1276 400.00 1 1 3 3
Shoes 1298 1050.00 4 2 1 4
Pants 1121 850.00 4 2 2 5
Hats 1288 400.00 6 2 3 6
Shoes 1298 950.00 6 3 1 7
Pants 1121 850.00 5 3 2 8
Hats 1401 150.00 4 3 3 9
Shoes 1321 970.00 2 4 1 10
Pants 1232 600.00 1 4 2 11
Hats 1408 270.00 5 4 3 12
Shoes 1750 1200.00 3 5 1 13
Pants 1232 400.00 7 5 2 14
Hats 1433 270.00 2 5 3 15
Shoes 1752 1150.00 5 6 1 16
Pants 1232 350.00 8 6 2 17
Hats 1434 290.00 3 6 3 18
Pants 1232 350.00 9 7 1 19
Pants 1233 600.00 3 8 1 20
Pants 1233 950.00 6 9 1 21
Pants 1233 980.00 11 10 1 22
Pants 1233 970.00 12 11 1 23
Pants 1260 350.00 10 12 1 24
Rn
содержит желаемые значения.
Попробуй это,
with cte as (select type, model,price, ROW_NUMBER() over (partition by type order by type) as rowid from temp)
select * from cte order by rowid, type