标记单个行的T-SQL

标记单个行的T-SQL,sql,tsql,cursor,Sql,Tsql,Cursor,我正在寻找一些T-SQL代码,该代码将添加一个名为tag的列,该列将用相同的数字标记每一行,直到“team”、“id”、“kmvid”、“name”、“cid”和“pid”列中的任何一列的值发生变化。如果有更改,请使用该行的下一个编号顺序。如图所示,请参见下面的预期结果 您可以使用累积和和滞后()来完成此操作。: 对于使用基于集合的操作可以更好地完成的事情,不应使用光标。以下内容将根据您拍摄的数据为您提供所需的结果 IF OBJECT_ID('tempdb..#TestData', 'U') I

我正在寻找一些T-SQL代码,该代码将添加一个名为tag的列,该列将用相同的数字标记每一行,直到“team”、“id”、“kmvid”、“name”、“cid”和“pid”列中的任何一列的值发生变化。如果有更改,请使用该行的下一个编号顺序。如图所示,请参见下面的预期结果


您可以使用累积和和
滞后()来完成此操作。


对于使用基于集合的操作可以更好地完成的事情,不应使用光标。

以下内容将根据您拍摄的数据为您提供所需的结果

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    CountryId CHAR(2) NOT NULL,
    [Date] DATETIME NOT NULL
    );
INSERT #TestData (CountryId, Date)
SELECT '99', '2004-04-30' UNION ALL 
SELECT '99', '2004-07-31' UNION ALL 
SELECT '99', '2004-10-31' UNION ALL 
SELECT '99', '2005-01-31' UNION ALL 
SELECT '99', '2005-04-30' UNION ALL 
SELECT '99', '2005-07-31' UNION ALL 
SELECT '99', '2005-10-31' UNION ALL
SELECT '99', '2006-01-31' UNION ALL 
SELECT '99', '2006-04-30' UNION ALL 
SELECT '99', '2006-07-31' UNION ALL 
SELECT '99', '2006-10-31' UNION ALL 
SELECT '99', '2007-01-31' UNION ALL 
SELECT 'HK', '2007-04-30' UNION ALL 
SELECT 'CA', '2007-07-31' UNION ALL 
SELECT 'HK', '2007-10-31';

--  SELECT * FROM #TestData td;

--=======================================

WITH 
    cte_TagGroup AS (
        SELECT 
            td.CountryId, 
            td.[Date],
            TagGroup = ROW_NUMBER() OVER (ORDER BY td.Date)
                - ROW_NUMBER() OVER (PARTITION BY td.CountryId ORDER BY td.Date)
                - CASE WHEN td.CountryId = LAG(td.CountryId, 1, td.CountryId) OVER (ORDER BY td.CountryId, td.Date) THEN 0 ELSE 1 END
        FROM
            #TestData td
        )
SELECT 
    tg.CountryId, 
    tg.Date, 
    Tag = DENSE_RANK() OVER (ORDER BY tg.TagGroup)
FROM
    cte_TagGroup tg;
。。。这就是说,我怀疑前3列数据不都是相同的值,因此您可能需要在“partitionby”子句中添加列,以使其适合您的实际数据

嗯,


Jason

您应该包括您的尝试,并提及数据库的版本。示例数据不包括
cid
pid
列。没有为行指定顺序。您尚未在数据库中标记问题,例如
sql server
。(
tsql
缩小了选择范围,但并不具体。)你没有尝试或研究的迹象。你没有包括一个问题。请阅读一些关于改进“问题”的提示。
IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData;

CREATE TABLE #TestData (
    CountryId CHAR(2) NOT NULL,
    [Date] DATETIME NOT NULL
    );
INSERT #TestData (CountryId, Date)
SELECT '99', '2004-04-30' UNION ALL 
SELECT '99', '2004-07-31' UNION ALL 
SELECT '99', '2004-10-31' UNION ALL 
SELECT '99', '2005-01-31' UNION ALL 
SELECT '99', '2005-04-30' UNION ALL 
SELECT '99', '2005-07-31' UNION ALL 
SELECT '99', '2005-10-31' UNION ALL
SELECT '99', '2006-01-31' UNION ALL 
SELECT '99', '2006-04-30' UNION ALL 
SELECT '99', '2006-07-31' UNION ALL 
SELECT '99', '2006-10-31' UNION ALL 
SELECT '99', '2007-01-31' UNION ALL 
SELECT 'HK', '2007-04-30' UNION ALL 
SELECT 'CA', '2007-07-31' UNION ALL 
SELECT 'HK', '2007-10-31';

--  SELECT * FROM #TestData td;

--=======================================

WITH 
    cte_TagGroup AS (
        SELECT 
            td.CountryId, 
            td.[Date],
            TagGroup = ROW_NUMBER() OVER (ORDER BY td.Date)
                - ROW_NUMBER() OVER (PARTITION BY td.CountryId ORDER BY td.Date)
                - CASE WHEN td.CountryId = LAG(td.CountryId, 1, td.CountryId) OVER (ORDER BY td.CountryId, td.Date) THEN 0 ELSE 1 END
        FROM
            #TestData td
        )
SELECT 
    tg.CountryId, 
    tg.Date, 
    Tag = DENSE_RANK() OVER (ORDER BY tg.TagGroup)
FROM
    cte_TagGroup tg;