Отфильтровать записи в течение n дней - PullRequest
0 голосов
/ 25 августа 2018

Я не уверен, как назвать этот вызов ..

Я хочу отметить (чтобы отфильтровать позже) определенные записи, разделенные столбцом TypeID, где они наблюдаются в течение n дней (в этом примере 3) от значения даты первой записи в разделенном набор данных. Это просто, но в том же многораздельном наборе, если больше записей появятся после ограничения в 3 дня - новая «первая» запись этой группы должна начать новую цепочку, чтобы отметить все последующие записи в течение 3 дней. И так далее ..

Я проиллюстрировал желаемый результат на этом снимке экрана, где я хочу отметить / отфильтровать строки, отмеченные желтым цветом. Все остальные строки должны быть сохранены.

enter image description here

Я распылял и молился с оконными функциями и т. Д., Но, похоже, не могу найти элегантного решения. Как бы вы подошли к этой проблеме с T-SQL?

sqlfiddle не отвечает с помощью sql-server atm, поэтому отправьте код DDL здесь:

DROP TABLE IF EXISTS [dbo].[testTable];

CREATE TABLE [dbo].[testTable](
    [RowID] [int] IDENTITY(1,1) NOT NULL PRIMARY KEY,
    [CustID] [int] NULL,
    [TransTypeID] [int] NULL,
    [Date] [date] NULL,
)
GO
SET IDENTITY_INSERT [dbo].[testTable] ON 
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (1, 9362, 1, CAST(N'2018-01-11' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (2, 9362, 1, CAST(N'2018-01-22' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (3, 9362, 2, CAST(N'2018-01-04' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (4, 9362, 2, CAST(N'2018-01-07' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (5, 9362, 2, CAST(N'2018-01-09' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (6, 9362, 2, CAST(N'2018-01-22' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (7, 9362, 2, CAST(N'2018-01-23' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (8, 9362, 2, CAST(N'2018-01-24' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (9, 9362, 2, CAST(N'2018-01-26' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (10, 9362, 3, CAST(N'2018-01-22' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (11, 9362, 5, CAST(N'2018-01-01' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (12, 9362, 5, CAST(N'2018-01-02' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (13, 9362, 5, CAST(N'2018-01-02' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (14, 9362, 5, CAST(N'2018-01-04' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (15, 9362, 5, CAST(N'2018-01-07' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (16, 9362, 5, CAST(N'2018-01-17' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (17, 9362, 5, CAST(N'2018-02-08' AS Date))
GO
INSERT [dbo].[testTable] ([RowID], [CustID], [TransTypeID], [Date]) VALUES (18, 9362, 5, CAST(N'2018-02-18' AS Date))
GO
SET IDENTITY_INSERT [dbo].[testTable] OFF
GO

1 Ответ

0 голосов
/ 25 августа 2018

Это должно быть возможно сделать с помощью рекурсивного CTE.Сначала SELECT все строки с минимальной датой в группе.Это можно сделать с помощью row_number().Затем рекурсивно UNION ALL строки с минимальной датой в группе, где дата больше максимальной даты, которая уже есть в результате плюс 3 дня, пропуская, таким образом, 3 дня.Снова row_number() может использоваться для этого и dateadd() для арифметики даты.

WITH [cte]
AS
(
SELECT [x].[RowID],
       [x].[CustID],
       [x].[TransTypeId],
       [x].[Date]
       FROM (SELECT [testTable].[RowID],
                    [testTable].[CustID],
                    [testTable].[TransTypeId],
                    [testTable].[Date],
                    row_number() OVER (PARTITION BY [testTable].[CustId],
                                                    [testTable].[TransTypeID]
                                       ORDER BY [testTable].[Date]) [row#]
                    FROM [dbo].[testTable]) [x]
       WHERE [x].[row#] = 1
UNION ALL
SELECT [x].[RowID],
       [x].[CustID],
       [x].[TransTypeId],
       [x].[Date]
       FROM (SELECT [testTable].[RowID],
                    [testTable].[CustID],
                    [testTable].[TransTypeId],
                    [testTable].[Date],
                    row_number() OVER (PARTITION BY [testTable].[CustId],
                                                    [testTable].[TransTypeID]
                                       ORDER BY [testTable].[Date]) [row#]
                    FROM [dbo].[testTable]
                         INNER JOIN [cte]
                                    ON [cte].[CustId] = [testTable].[CustId]
                                       AND [cte].[TransTypeId] = [testTable].[TransTypeID]
                                       AND dateadd(day, 3, [cte].[Date]) < [testTable].[Date]) [x]
       WHERE [x].[row#] = 1
)
SELECT *
       FROM [cte]
       ORDER BY [cte].[CustID],
                [cte].[TransTypeID],
                [cte].[Date];

Результат:

RowID | CustID | TransTypeId | Date               
----: | -----: | ----------: | :------------------
    1 |   9362 |           1 | 11/01/2018 00:00:00
    2 |   9362 |           1 | 22/01/2018 00:00:00
    3 |   9362 |           2 | 04/01/2018 00:00:00
    5 |   9362 |           2 | 09/01/2018 00:00:00
    6 |   9362 |           2 | 22/01/2018 00:00:00
    9 |   9362 |           2 | 26/01/2018 00:00:00
   10 |   9362 |           3 | 22/01/2018 00:00:00
   11 |   9362 |           5 | 01/01/2018 00:00:00
   15 |   9362 |           5 | 07/01/2018 00:00:00
   16 |   9362 |           5 | 17/01/2018 00:00:00
   17 |   9362 |           5 | 08/02/2018 00:00:00
   18 |   9362 |           5 | 18/02/2018 00:00:00

db <> fiddle

(Я предположил, что группы определяются не только [TransTypeID], но и [CustID]. Мне это было не совсем понятно. Если мое предположение неверно, удалите [CustID] из предложений PARTITION BY.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...