基于特定列过滤器为信息块创建ID

时间:2017-08-10 13:20:01

标签: sql-server

在我的桌子上,我有4列。我需要创建一个过程(或一个简单的查询),根据特定的列过滤器为一个信息块创建ID。

更好的解释,

我有这些信息(请注意第2和第3栏):

PK_ID_TBL_POINTS_AND_CYCLES|TEMP_NUMBER|TYPE|_Date
18953|NULL|AAAA|2017-06-28 09:01:00.000
18954|NULL|AAAA|2017-06-28 09:01:00.000
7847|NULL|BBBB|2017-06-26 09:01:00.000
7848|NULL|BBBB|2017-06-26 09:01:00.000
7849|NULL|BBBB|2017-06-26 09:02:00.000
13444|NULL||2017-06-28 10:06:00.000
13445|NULL||2017-06-28 10:07:00.000
13447|NULL||2017-06-28 10:07:00.000
14953|NULL|AAAA|2017-06-28 14:16:00.000
14954|NULL|AAAA|2017-06-28 14:16:00.000
14955|NULL|AAAA|2017-06-28 14:17:00.000
14956|NULL|AAAA|2017-06-28 14:17:00.000
15134|NULL|AAAA|2017-06-28 14:46:00.000
15135|NULL|AAAA|2017-06-28 14:46:00.000
15138|NULL|AAAA|2017-06-28 14:47:00.000
15139|NULL|AAAA|2017-06-28 14:47:00.000
15140|NULL|AAAA|2017-06-28 14:47:00.000

我需要得到这个(注意第2和第3个字段):

PK_ID_TBL_POINTS_AND_CYCLES|TEMP_NUMBER|TYPE|_Date
18953|1|AAAA|2017-06-28 09:01:00.000
18954|1|AAAA|2017-06-28 09:01:00.000
7847|NULL|BBBB|2017-06-26 09:01:00.000
7848|NULL|BBBB|2017-06-26 09:01:00.000
7849|NULL|BBBB|2017-06-26 09:02:00.000
13444|NULL||2017-06-28 10:06:00.000
13445|NULL||2017-06-28 10:07:00.000
13447|NULL||2017-06-28 10:07:00.000
14953|2|AAAA|2017-06-28 14:16:00.000
14954|2|AAAA|2017-06-28 14:16:00.000
14955|2|AAAA|2017-06-28 14:17:00.000
14956|2|AAAA|2017-06-28 14:17:00.000
15134|2|AAAA|2017-06-28 14:46:00.000
15135|2|AAAA|2017-06-28 14:46:00.000
15138|2|AAAA|2017-06-28 14:47:00.000
15139|2|AAAA|2017-06-28 14:47:00.000
15140|2|AAAA|2017-06-28 14:47:00.000

此表的订单将为:

order by th._Date,tc.PK_ID_TBL_POINTS_AND_CYCLES

注意:在我糟糕的例子中,我在_Date上发了一个订单,但我忘了在PK_ID_TBL_POINTS_AND_CYCLE上做。正确的是按日期(第4列)和ID(第1列)的顺序。

我只关心第3列= AAAA。如果它是AAAA,我应该创建一个数字(这个信息块的标识符)。在我的例子中,我为第一个AAAA块创建了ID 1,为第二个AAAA块创建了ID 2。我不在乎<>比AAAA。

那么,我应该如何处理这个问题?我的第一个想法是逐行进行并检查下一个是否相同,如果是,我继续前进,直到找到<>一。但正如this answer指出的那样,这将非常缓慢。另外,我更熟悉C#,使用foreach循环一行一行非常简单,我不确定Sequel有多简单。

2 个答案:

答案 0 :(得分:1)

试试这个(SQL 2012 +):

DECLARE @YourTable TABLE(
    PK_ID_TBL_POINTS_AND_CYCLES INT, T INT, [TYPE] VARCHAR(256), _Date DATETIME
)
INSERT INTO @YourTable VALUES
(18953, NULL, 'AAAA', '2017-06-28 09:01:00.000'),
(18954, NULL, 'AAAA', '2017-06-28 09:01:00.000'),
(7847, NULL,  'BBBB', '2017-06-28 09:01:00.000'),
(7848, NULL,  'BBBB', '2017-06-28 09:01:00.000'),
(7849, NULL,  'BBBB', '2017-06-28 09:02:00.000'),
(13444, NULL,     '', '2017-06-28 14:06:00.000'),
(13445, NULL,     '', '2017-06-28 14:07:00.000'),
(13447, NULL,     '', '2017-06-28 14:07:00.000'),
(14953, NULL, 'AAAA', '2017-06-28 12:16:00.000'),
(14954, NULL, 'AAAA', '2017-06-28 12:16:00.000'),
(14955, NULL, 'AAAA', '2017-06-28 12:17:00.000'),
(14956, NULL, 'AAAA', '2017-06-28 14:17:00.000'),
(15134, NULL, 'AAAA', '2017-06-28 14:46:00.000'),
(15135, NULL, 'AAAA', '2017-06-28 14:46:00.000'),
(15138, NULL, 'AAAA', '2017-06-28 14:47:00.000'),
(15139, NULL, 'AAAA', '2017-06-28 14:47:00.000'),
(15140, NULL, 'AAAA', '2017-06-28 14:47:00.000')

DECLARE @Type VARCHAR(256) = 'AAAA';
WITH Marked AS (
    SELECT PK_ID_TBL_POINTS_AND_CYCLES, [TYPE], _Date,
        TypeChanged = IIF(LAG([TYPE]) OVER (ORDER BY _Date,PK_ID_TBL_POINTS_AND_CYCLES) = [TYPE] OR [TYPE] <> @Type, 0, 1)
    FROM @YourTable
)
SELECT PK_ID_TBL_POINTS_AND_CYCLES, [TYPE], _Date,
    TEMP_NUMBER = IIF([TYPE] = @TYPE, SUM(TypeChanged) OVER (ORDER BY _Date,PK_ID_TBL_POINTS_AND_CYCLES), NULL)
FROM Marked
WHERE TYPE = @Type
ORDER BY _Date,PK_ID_TBL_POINTS_AND_CYCLES

答案 1 :(得分:0)

您可以查询如下:

;With cte as (
    Select *, Rnk = Sum(ChangeIdentifier) over(order by [date]) from (
        Select *, ChangeIdentifier = case when [type] <> lag([type]) over(order by [date]) then 1 else 0 end from #tempdata
    ) a 
) Select dense_rank() over(order by case when [Type] = 'AAAA' then Rnk else 0 end)-1, * from cte
order by [date]
相关问题