当某些行中的2行具有相同的值时,请使用其他行account_no设置一个新列

时间:2018-10-29 20:52:06

标签: sql sql-server tsql

我正在尝试填充表格中的&&

IL_0000:  nop
IL_0001:  ldarg.0
IL_0002:  stloc.0
IL_0003:  ldarg.1
IL_0004:  stloc.1
IL_0005:  ldloca.s   V_0
IL_0007:  call       instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_000c:  ldloca.s   V_1
IL_000e:  call       instance !0 valuetype [mscorlib]System.Nullable`1<int32>::GetValueOrDefault()
IL_0013:  beq.s      IL_0018

IL_0015:  ldc.i4.0
IL_0016:  br.s       IL_0028

IL_0018:  ldloca.s   V_0
IL_001a:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_001f:  ldloca.s   V_1
IL_0021:  call       instance bool valuetype [mscorlib]System.Nullable`1<int32>::get_HasValue()
IL_0026:  ceq
IL_0028:  call       void [mscorlib]System.Console::WriteLine(bool)
IL_002d:  nop
IL_002e:  ret

带有新列AccountKey的输出表如下所示。

CREATE TABLE mytable
(
     sub_no        INTEGER NOT NULL PRIMARY KEY 
     ,account_no   INTEGER NOT NULL
     ,rep          VARCHAR(1) NOT NULL
     ,security_no  INTEGER NOT NULL
     ,symbol       VARCHAR(1) NOT NULL
     ,asofdate     DATE NOT NULL
     ,qty          INTEGER NOT NULL
     ,abs_qty      INTEGER NOT NULL
     ,CrossAccount BIT NOT NULL
);

INSERT INTO mytable (sub_no, account_no, rep, security_no, symbol, asofdate, qty, abs_qty, CrossAccount,) 
VALUES (177, 12345, 'X', 2000, 'A', '20180101', 100, 100, 1), 
       (177, 23456, 'Y', 2000, 'A', '20180101', -100, 100, 1),
       (177, 34567, 'Z', 5000, 'A', '20180101', 300, 300, 0),
       (177, 45455, 'Z', 5000, 'A', '20170909', 300, 300, 0),
       (160, 65432, 'A', 9999, 'B', '20180202', -500, 500, 1),
       (160, 54321, 'B', 9999, 'C', '20180202', 500, 500, 1);

当security_no,asofdate和abs_qty相同时,则将CrossAcct值填充为1。

当CrossAcct值为1时,两个具有相同security_no,asofdate和abs_qty的帐户,每个帐户都应具有另一个帐户的AccountKey = sub_no +'-'+ account_no。

在上表中,条目1和2具有相同的security_no,asofdate和abs_qty。因此,对于第一个条目,AccountKey = 177-23456,这是该对中第二个条目的sub_no和account_no。

因此,只要两行具有相同的security_no,asoddate和abs_qty,则应从第二行的sub_no和account_no填充第一行的AccountKey,反之亦然。

1 个答案:

答案 0 :(得分:0)

有几种方法可以根据您的样本数据获得所需的结果。

一种方法是使用左自我连接...

SELECT 
    mt1.*,
    AccountKey = CONVERT(VARCHAR(10), mt1.sub_no) + '-' + CONVERT(VARCHAR(10), mt2.account_no)
FROM
    #mytable mt1
    LEFT JOIN #mytable mt2
        ON mt1.sub_no = mt2.sub_no
        AND mt1.security_no = mt2.security_no
        AND mt1.asofdate = mt2.asofdate
        AND mt1.abs_qty = mt2.abs_qty
        AND mt1.qty + mt2.qty = 0;

另一种选择是使用LEAD和LAG功能...

SELECT 
    mt.*,
    AccountKey = ISNULL(LEAD(CONCAT(mt.sub_no, '-', mt.account_no), 1) OVER (PARTITION BY mt.sub_no, mt.security_no, mt.asofdate, mt.abs_qty ORDER BY mt.qty),
    LAG(CONCAT(mt.sub_no, '-', mt.account_no), 1) OVER (PARTITION BY mt.sub_no, mt.security_no, mt.asofdate, mt.abs_qty ORDER BY mt.qty))
FROM
    #mytable mt;