Задачка:
Есть табличка с 3мя полями
ID DATE QTY
Для каждого клиента(ID) каждый день(DATE) может быть запись с количеством(QTY) N.
Нужно выбрать для каждого клиента(ID) все записи по такому принципу:
1. Находим для ID первую запись, где QTY больше 5 (если меньше - пропускаем) - выбираем эту запись
2. Находим для ID следующую запись, где QTY больше 5 и прошло не меньше 14 дней от даты предыдущей выбранной записи - выбираем эту запись
3. Повторяем итерацию 2, пока не выберем все записи
Решение.
Создаем табличку с тестовыми данными:
CREATE TABLE #tab (
ID integer,
[DATE] datetime,
QTY integer
)
INSERT INTO #tab (ID,[DATE],QTY)
VALUES (1, '20140101', 5),(1, '20140102', 7), (1, '20140108', 2),
(1, '20140115', 12), (1, '20140122', 1),(1, '20140202', 2),
(1, '20140208', 5), (1, '20140218', 8),(2, '20140101', 6),
(2, '20140102', 1), (2, '20140108', 11),(2, '20140115', 5),
(2, '20140122', 8),(2, '20140202', 12), (2, '20140208', 3),
(2, '20140218', 6)
Я использовал рекурсию в CTE
WITH a AS (
SELECT * FROM (
SELECT ID,
[DATE],
QTY,
DATEADD(DAY, 14, [DATE]) AS MinNextDate ,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [DATE]) AS rn
FROM #tab
WHERE QTY > 5
)b
WHERE rn = 1
UNION ALL
SELECT * FROM (
SELECT c.ID,
c.[DATE],
c.QTY,
DATEADD(DAY, 14, c.[DATE]) AS MinNextDate ,
ROW_NUMBER() OVER (PARTITION BY c.ID ORDER BY c.[DATE]) AS rn
FROM #tab c
JOIN a
ON c.ID = a.ID
AND c.[DATE] >= a.MinNextDate
WHERE c.QTY > 5
)b
WHERE rn = 1
)
SELECT ID,[DATE], QTY
FROM a
ORDER BY ID, [DATE], QTY
Результат выполнения запроса:
Про рекурсию в CTE: http://www.sql-tutorial.ru/ru/book_recursive_cte/page3.html
Есть табличка с 3мя полями
ID DATE QTY
Для каждого клиента(ID) каждый день(DATE) может быть запись с количеством(QTY) N.
Нужно выбрать для каждого клиента(ID) все записи по такому принципу:
1. Находим для ID первую запись, где QTY больше 5 (если меньше - пропускаем) - выбираем эту запись
2. Находим для ID следующую запись, где QTY больше 5 и прошло не меньше 14 дней от даты предыдущей выбранной записи - выбираем эту запись
3. Повторяем итерацию 2, пока не выберем все записи
Решение.
Создаем табличку с тестовыми данными:
CREATE TABLE #tab (
ID integer,
[DATE] datetime,
QTY integer
)
INSERT INTO #tab (ID,[DATE],QTY)
VALUES (1, '20140101', 5),(1, '20140102', 7), (1, '20140108', 2),
(1, '20140115', 12), (1, '20140122', 1),(1, '20140202', 2),
(1, '20140208', 5), (1, '20140218', 8),(2, '20140101', 6),
(2, '20140102', 1), (2, '20140108', 11),(2, '20140115', 5),
(2, '20140122', 8),(2, '20140202', 12), (2, '20140208', 3),
(2, '20140218', 6)
Я использовал рекурсию в CTE
WITH a AS (
SELECT * FROM (
SELECT ID,
[DATE],
QTY,
DATEADD(DAY, 14, [DATE]) AS MinNextDate ,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY [DATE]) AS rn
FROM #tab
WHERE QTY > 5
)b
WHERE rn = 1
UNION ALL
SELECT * FROM (
SELECT c.ID,
c.[DATE],
c.QTY,
DATEADD(DAY, 14, c.[DATE]) AS MinNextDate ,
ROW_NUMBER() OVER (PARTITION BY c.ID ORDER BY c.[DATE]) AS rn
FROM #tab c
JOIN a
ON c.ID = a.ID
AND c.[DATE] >= a.MinNextDate
WHERE c.QTY > 5
)b
WHERE rn = 1
)
SELECT ID,[DATE], QTY
FROM a
ORDER BY ID, [DATE], QTY
Результат выполнения запроса:
Про рекурсию в CTE: http://www.sql-tutorial.ru/ru/book_recursive_cte/page3.html
Комментариев нет:
Отправить комментарий