将行号设置为各种操作

时间:2013-01-14 05:20:33

标签: sql sql-server sql-server-2005 row-number

我正在尝试将行号设置为表的输出。

表格如

AccountNum  DataAction  ActionType  ActionStartCounter
123         11/01/2013  HELLO       1
123         12/01/2013  NONO        NULL
123         16/01/2013  YESYES      NULL
123         1/02/2013   HELLO       2
123         4/02/2013   YESYES      NULL
456         10/01/2013  HELLO       1
456         13/01/2013  NONO        NULL
456         14/01/1900  WHYWHY      NULL
456         15/01/2013  YESYES      NULL
456         20/03/2013  HELLO       2
456         31/03/2013  YESYES      NULL

这是尝试做的是

1)每次帐户都有Hello时,它会根据ActionStartCounter

下的DateAction对表进行排序

2)NULLs表示这些行为不是HELLO并且是Previous Numbered行的一部分

i.e. for AccountNum 123 NONO on 12/01/2013 is linked to HELLO on 11/01/2013.

3)YESYES是HELLO任何开始的任何账户的最后一次行动。

我希望输出为

AccountNum  DataAction  ActionType  ActionStartCounter    ActionCounter
123         11/01/2013  HELLO       1                     11
123         12/01/2013  NONO        NULL                  12
123         16/01/2013  YESYES      NULL                  13
123         1/02/2013   HELLO       2                     21
123         4/02/2013   YESYES      NULL                  22
456         10/01/2013  HELLO       1                     11
456         13/01/2013  NONO        NULL                  12
456         14/01/1900  WHYWHY      NULL                  13
456         15/01/2013  YESYES      NULL                  14
456         20/03/2013  HELLO       2                     21
456         31/03/2013  YESYES      NULL                  22

新字段ActionCounter基本上是

的串联

ActionStartCounter以及accountNumActionStartCounter

中的rownumber

含义

连接中的第二部分是关于HELLO开始时的row_number,只要新的HELLO进入计数器重置。

ActionStartCounter也基于ActionType ='Hello' then row_number()结束时的情况(按DateNction按AccountNum排序)

如果你们认为应该改变,我们可以做到这一点。如果您认为AccountNum或Date可以成为新列的一部分以使其唯一,我们就可以做到这一点。我们需要转换到最后一列的字段数量没有限制。

感谢您的帮助。

PS:平台SQL Server 2005

这是DDL

Create Table ActionDetails
(
AccountNum Int,
DataAction datetime,
ActionType Varchar(25),
ActionStart int 
)

Insert into ActionDetails
Select 123,CONVERT(datetime,'20130111' ,112),'HELLO',1 UNION 
Select 123,CONVERT(datetime,'20130112' ,112),'NONO',NULL UNION 
Select 123,CONVERT(datetime,'20130116' ,112),'YESYES',NULL UNION 
Select 123,CONVERT(datetime,'20130201' ,112),'HELLO',2 UNION 
Select 123,CONVERT(datetime,'20130204' ,112),'YESYES',NULL UNION 
Select 456,CONVERT(datetime,'20130110' ,112),'HELLO',1 UNION 
Select 456,CONVERT(datetime,'20130113' ,112),'NONO',NULL UNION 
Select 456,CONVERT(datetime,'20130114' ,112),'WHYWHY',NULL UNION 
Select 456,CONVERT(datetime,'20130115' ,112),'YESYES',NULL UNION 
Select 456,CONVERT(datetime,'20130320' ,112),'HELLO',2 UNION 
Select 456,CONVERT(datetime,'20130331' ,112),'YESYES',NULL 

2 个答案:

答案 0 :(得分:1)

(456不以HELLO开头 - 不确定如何处理)。 不得不重写你的日期,可能在那里犯了错误。虽然机制应该是合理的。

;WITH MyTable (AccountNum,  DataAction,  ActionType,  ActionStartCounter) AS
(
SELECT 123,         CAST('01/11/2013' AS DATETIME),  'HELLO',       1       UNION ALL
SELECT 123,         '01/12/2013',  'NONO',        NULL  UNION ALL
SELECT 123,         '01/16/2013',  'YESYES',      NULL  UNION ALL
SELECT 123,         '2/1/2013',   'HELLO',       2      UNION ALL
SELECT 123,         '2/4/2013',   'YESYES',      NULL   UNION ALL
SELECT 456,         '1/10/2013',  'HELLO',       1      UNION ALL
SELECT 456,         '1/13/2013',  'NONO',        NULL   UNION ALL
SELECT 456,         '1/14/1900',  'WHYWHY',      NULL   UNION ALL
SELECT 456,         '01/15/2013',  'YESYES',      NULL  UNION ALL
SELECT 456,         '03/20/2013',  'HELLO',       2     UNION ALL
SELECT 456,         '3/31/2013',  'YESYES',      NULL   
)
,CTE AS
(
    SELECT   * 
            ,SeqGroupAcc    = ROW_NUMBER() OVER (PARTITION BY AccountNum ORDER BY DataAction)
    FROM MyTable
)
,CTE2 AS
(
    SELECT   *
            ,MyCounting = 1
    FROM CTE
    WHERE SeqGroupAcc = 1
    UNION ALL
    SELECT   T2.AccountNum
            ,T2.DataAction
            ,T2.ActionType
            ,CASE WHEN T2.ActionStartCounter IS NULL THEN T1.ActionStartCounter ELSE  T2.ActionStartCounter END
            ,T2.SeqGroupAcc
            ,CASE WHEN T2.ActionType = 'HELLO' THEN 1 ELSE T1.MyCounting + 1 END
    FROM CTE2   T1
    JOIN CTE    T2 ON T1.SeqGroupAcc = T2.SeqGroupAcc - 1 AND T1.AccountNum = T2.AccountNum
)                                                       
SELECT   AccountNum
        ,DataAction
        ,ActionType
        ,ActionStartCounter
        ,ActionCounter  = (ActionStartCounter) * 10 + MyCounting
--OR: ,ActionCounter    = CAST(ActionStartCounter AS VARCHAR(5)) + CAST(MyCounting AS VARCHAR(5))
FROM CTE2
WHERE AccountNum = 123

答案 1 :(得分:0)

我认为this基本上是相同的方法 - 必须有更好的方法吗?