0

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

表看起来像

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 时,它都会根据列下的 DateAction 对表进行排序ActionStartCounter

2)NULLs表示这些动作不是 HELLO 并且是先前编号行的一部分

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

意义

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

ActionStartCounter 也基于结束时的情况ActionType ='Hello' then row_number()(按 AccountNum 顺序按 DateAction 分区)

如果你们认为应该改变,我们可以完成。如果您认为 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 
4

2 回答 2

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
于 2013-01-14T05:53:08.860 回答
0

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

于 2013-01-14T06:59:37.140 回答