Установить номер строки для пакета из N строк на категорию - PullRequest
1 голос
/ 28 мая 2020

У меня есть таблица

+-----+----------+---------+
| id  | name     | phase   |
+-----+----------+---------+
| 101 | Bolt     | PHASE 1 |
| 102 | Nut      | PHASE 1 |
| 103 | Screw    | PHASE 1 |
| 104 | Hex BOLT | PHASE 1 |
| 105 | Rubber   | PHASE 1 |
| 106 | Aluminum | PHASE 2 |
| 107 | Slate    | PHASE 2 |
| 108 | Pen      | PHASE 3 |
| 109 | Pencil   | PHASE 3 |
| 110 | Mouse    | PHASE 3 |
| 111 | Keyboard | PHASE 3 |
+-----+----------+---------+

Я хочу создать еще один столбец, в который мне нужно указать номер строки.

Logi c: для 3 строк он должен быть таким же и измениться на следующее значение для 4-й строки. И всякий раз, когда ФАЗА изменяется, она должна go перейти к следующему числу, даже если набор из 3 не завершен для предыдущего числа.

Ожидаемый результат

+-----+----------+---------+-----+
| id  | name     | phase   | SET |
+-----+----------+---------+-----+
| 101 | Bolt     | PHASE 1 | 1   |
| 102 | Nut      | PHASE 1 | 1   |
| 103 | Screw    | PHASE 1 | 1   |
| 104 | Hex BOLT | PHASE 1 | 2   |
| 105 | Rubber   | PHASE 1 | 2   |
| 106 | Aluminum | PHASE 2 | 3   |
| 107 | Slate    | PHASE 2 | 3   |
| 108 | Pen      | PHASE 3 | 4   |
| 109 | Pencil   | PHASE 3 | 4   |
| 110 | Mouse    | PHASE 3 | 4   |
| 111 | Keyboard | PHASE 3 | 5   |
+-----+----------+---------+-----+

Я пробовал ниже запроса, но он не дает мне требуемого вывода.

select *, (row_number() over (order by phase)-1) / 3 as sets
from table_main

Фактический результат:

+-----+----------+---------+------+
| id  | name     | phase   | sets |
+-----+----------+---------+------+
| 101 | Bolt     | PHASE 1 | 0    |
| 102 | Nut      | PHASE 1 | 0    |
| 103 | Screw    | PHASE 1 | 0    |
| 104 | Hex BOLT | PHASE 1 | 1    |
| 105 | Rubber   | PHASE 1 | 1    |
| 106 | Aluminum | PHASE 2 | 1    |
| 107 | Slate    | PHASE 2 | 2    |
| 108 | Pen      | PHASE 3 | 2    |
| 109 | Pencil   | PHASE 3 | 2    |
| 110 | Mouse    | PHASE 3 | 3    |
| 111 | Keyboard | PHASE 3 | 3    |
+-----+----------+---------+------+ 

Я также пробовал с DENSE_RANK(), но не получил ожидаемого результата.

СКРЫТЬ ЗДЕСЬ

Ответы [ 2 ]

2 голосов
/ 03 июня 2020

Попробуйте:

WITH CTE
as
(
select *, ROW_NUMBER () OVER (PARTITION BY phase ORDER BY id) as rn
from table_main
)
SELECT *,DENSE_RANK() over (ORDER BY phase ,CEILING(rn/3.0)) as set
FROM CTE
1 голос
/ 03 июня 2020

Используйте LAG, чтобы получить значение предыдущей строки для column, и если оно изменилось, добавьте 1. Используйте ROW_NUMBER(), как указано, с %3, а затем sum те значения, которые указаны ниже.

;WITH tm AS (
    SELECT *, 
            IIF((LAG(phase, 1) OVER (ORDER BY phase, id)) = phase, 0, 1) AS phase_change,
            IIF((ROW_NUMBER() OVER (PARTITION BY phase ORDER BY phase)-1)%3 = 0, 1, 0) AS [set]
    FROM table_main
) 
SELECT id, 
        name, 
        phase,
        SUM(IIF([set] > phase_change, [set], phase_change)) OVER (ORDER BY phase, id) AS [set]
FROM tm
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...