2

次のように、SQL ステートメントを使用してフィールド [Allocation] の連続する値を比較しています。

;WITH cteMain AS
(SELECT AllocID, CaseNo, FeeEarner, Allocation, ROW_NUMBER() OVER (ORDER BY AllocID) AS sn
FROM tblAllocations)

SELECT m.AllocID, m.CaseNo, m.FeeEarner, m.Allocation, 
       ISNULL(sLag.Allocation, 0) AS prevAllocation,
      (m.Allocation - ISNULL(sLag.Allocation, 0)) AS movement
FROM cteMain AS m

LEFT OUTER JOIN cteMain AS sLag
ON sLag.sn = m.sn-1;

クエリは、[Allocation] の連続した値の増加または減少である計算フィールド [movement] を返します。

このクエリによって返されるデータのスクリーン ショットを含めました。

返されたデータのスクリーンショット

ただし、クエリはまだ完了していません。比較される [Allocation] の連続する値が [FeeEarner] と [CaseNo] によってグループ化/分割されるように、ステートメントを修正する必要があります。

たとえば、データの 18 行目の [Allocation] は 800 で、前の値の 600 と比較されます。しかし、前の値は別の [CaseNo]、つまり 31 ではなく 6 に属します。実際には [FeeEarner] 'PJW ' [CaseNo] '31' には以前の [Allocation] がないため、[prevAllocation] は ISNULL キーワードから '0' である必要があります。

変えてみました

OVER (ORDER BY AllocID)

OVER (PARTITION BY CaseNo, FeeEarner ORDER BY AllocID) 

しかし、その結果、多くのデータ行が繰り返されます。

[Allocation] の連続した値を比較する方法を誰かがアドバイスできますが、[FeeEarner] と [CaseNo] が一致するデータの行間のみを比較してください。

- 私の顧客は並列データ ウェアハウスをサポートしていない SQL Server 2008 R2 を使用しているため、LAG を使用できません。

4

3 に答える 3

3

私はあなたが近くにいたと信じています。これを試してください(パーティションに一致するように結合句に追加された部分に注意してください-これがないと、パーティション全体ですべての行番号3とすべての行番号2が一致します。これはあなたが見ていたことです):

;WITH cteMain AS
(
    SELECT AllocID, CaseNo, FeeEarner, Allocation, 
        ROW_NUMBER() OVER (PARTITION BY CaseNo, FeeEarner ORDER BY AllocID) AS sn
    FROM tblAllocations
)    
SELECT m.AllocID, m.CaseNo, m.FeeEarner, m.Allocation, 
       ISNULL(sLag.Allocation, 0) AS prevAllocation,
      (m.Allocation - ISNULL(sLag.Allocation, 0)) AS movement
FROM cteMain AS m

LEFT OUTER JOIN cteMain AS sLag
    ON sLag.CaseNo = m.CaseNo
    AND sLag.FeeEarner = m.FeeEarner
    AND sLag.sn = m.sn-1
于 2013-02-07T16:02:39.287 に答える
0

OUTER APPLY と EXISTS を使用したもう 1 つのオプション

SELECT t1.AllocID, t1.CaseNo, t1.FreeEarner, t1.Allocation, 
       ISNULL(o.Allocation, 0) AS PrevAllocation, 
       (t1.Allocation - ISNULL(o.Allocation, 0)) AS movement
FROM tblAllocations t1 
OUTER APPLY (
             SELECT t2.AllocID, t2.CaseNo, t2.FreeEarner, t2.Allocation
             FROM tblAllocations t2
             WHERE EXISTS (
                           SELECT 1
                           FROM tblAllocations t3
                           WHERE t1.AllocID > t3.AllocID
                           HAVING MAX(t3.AllocID) = t2.AllocID
                           ) AND t1.CaseNo = t2.CaseNo
             ) o
于 2013-02-07T16:52:08.963 に答える
0

結合条件も変更する必要があります。

FROM cteMain m LEFT OUTER JOIN
     cteMain sLag
     ON sLag.sn = m.sn-1 and sLag.FeeEarner = m.FeeEarner and slag.CaseNo = m.CaseNo

order byまた、row_number()通話には 1 つだけを使用する必要があります。

また、Oracle、SQL Server 2012、新しいバージョンの DB2、または Postgres を使用している場合は、lead()/lag()関数を使用することをお勧めします。

于 2013-02-07T15:59:00.857 に答える