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 は基本的に連結されます

ActionStartCounterand 内の行accountNum番号ActionStartCounter

意味

連結の 2 番目の部分は、新しい HELLO がカウンター リセットに入るとすぐに、HELLO の開始内の row_number に関するものです。

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 に答える