1

请帮助解决以下问题:

在下表(示例)中,Dayscount 字段应该具有当前行中的 Txndate 和下一行中的 Txndate 之间的差异,前提是两行中的 Acctno 相同。如果 AcctNo 不同,则 Dayscount 应从给定的固定日期派生 - (示例中使用了 2012 年 3 月 31 日)。Product 列将包含 Amount1 和 DaysCount 的乘积

+--------+------------------+----------------------+---------+-------------+----------+
|  P_ID  |      AcctNo      |              TxnDate | Amount1 |   DAYSCOUNT |  Product |
+--------+------------------+----------------------+---------+-------------+----------+
| 108161 | 0019061_A0100501 | 30/01/2012           |     250 |             |          |
| 108162 | 0019061_A0100501 | 03/02/2012           |  -23000 |             |          |
| 108163 | 0019061_A0100502 | 09/02/2012           |    -215 |             |          |
| 108164 | 0019061_A0100502 | 24/02/2012           |   -1103 |             |          |
+--------+------------------+----------------------+---------+-------------+----------+

预期输出如下所示:

+--------+------------------+--------------------------+----------+-----------+---------------+
|  P_ID  |      AcctNo      |              TxnDate     | Amount1  | DAYSCOUNT |    Product    |
+--------+------------------+--------------------------+----------+-----------+---------------+
| 108161 | 0019061_A0100501 | 30/01/2012               |      250 |         4 |          1000 |
| 108162 | 0019061_A0100501 | 03/02/2012               |   -23000 |        57 |      -1311000 |
| 108163 | 0019061_A0100502 | 09/02/2012               |     -215 |        15 |         -3225 |
| 108164 | 0019061_A0100502 | 24/02/2012               |    -1103 |        36 |        -39708 |
|        |                  |                          |          |           |               |
+--------+------------------+--------------------------+----------+-----------+---------------+
4

3 回答 3

0

将选项与OUTER APPLY运算符一起使用。

每次对左表表达式中的每一行处理右表表达式。最终结果集包含从左表表达式中选择的所有列,然后是右表表达式的所有列。OUTER APLLY 对于右表表达式中没有对应匹配的那些行,它在右表表达式的列中包含 NULL 值。

SELECT t.P_ID, t.AcctNo, t.TxnDate, Amount1, 
       DATEDIFF(day, t.TxnDate, CASE WHEN t.AcctNo = o.AcctNo THEN o.TxnDate ELSE '20120331' END) AS DAYSCOUNT,
       DATEDIFF(day, t.TxnDate, CASE WHEN t.AcctNo = o.AcctNo THEN o.TxnDate ELSE '20120331' END) * Amount1 AS Product
FROM dbo.test76 t OUTER APPLY (
                               SELECT TOP 1 t2.TxnDate, t2.AcctNo
                               FROM dbo.test76 t2
                               WHERE t.P_ID < t2.P_ID
                               ORDER BY P_ID ASC
                               ) o

SQLFiddle上的演示

为了提高性能,请使用此索引

CREATE INDEX x ON dbo.test76(P_ID) INCLUDE(AcctNo, TxnDate, Amount1)
于 2013-04-04T11:06:47.457 回答
0

如果它需要一次又一次地循环表,请考虑使用递归与类

于 2013-04-04T11:08:52.587 回答
0
WITH CTE AS (
    SELECT ROW_NUMBER() OVER(ORDER BY P_ID) AS RowNumber, *
    FROM TableName)

SELECT CTE1.P_ID,
       CTE1.AcctNo,
       CTE1.TxnDate,
       CTE1.Amount1, 
       DATEDIFF (DD, 
          CTE1.TxnDate,
          CASE WHEN CTE1.AcctNo = ISNULL(CTE2.AcctNo,'')
               THEN CTE2.TxnDate
               ELSE '20120331'
          END) AS DAYSCOUNT,
       DATEDIFF (DD,
          CTE1.TxnDate,
          CASE WHEN CTE1.AcctNo = ISNULL(CTE2.AcctNo,'')
               THEN CTE2.TxnDate
               ELSE '20120331'
          END) * CTE1.Amount1 AS Product
       FROM CTE AS CTE1
LEFT JOIN CTE AS CTE2 ON (CTE1.RowNumber + 1 = CTE2.RowNumber)
于 2013-04-04T11:21:49.060 回答