仅在组中的第一行左外连接

时间:2015-06-16 13:53:04

标签: sql-server sql-server-2008

我有一个看起来像这样的表:

BANK        ACCOUNT_NAME    EXCESS  DEBT
Acme Bank   Checking1       500     300
Acme Bank   Personal        200     100
Bank One    Business        100     50

我需要一个返回的SQL查询。

BANK        ACCOUNT_NAME    EXCESS  DEBT    AVAILABLE
Acme Bank   Checking1       500     300     300
Acme Bank   Personal        200     100     NULL
Bank One    Business        100     50      50

AVAILABLE是由Sum(EXCESS) - Sum(DEBT)分组的BANK。然后,AVAILABLE将仅出现在BANK-ACCOUNT_NAME组合的第一行。我该怎么做?

我的第一次尝试导致AVAILABLE在所有行上具有值,这不是预期的。我只希望中的第一行具有AVAILABLE值。

SELECT
    outer.BANK
    ,outer.ACCOUNT_NAME
    ,outer.EXCESS
    ,outer.DEBT
    ,inner2.AVAILABLE
FROM BankBalances AS outer
CROSS APPLY
    (
        SELECT TOP 1
            Bank
            ,SUM(EXCESS) - SUM(DEBT) AS AVAILABLE
        FROM BankBalances AS inner
        GROUP BY Bank
        WHERE outer.BANK = inner.BANK
    ) AS inner2

2 个答案:

答案 0 :(得分:3)

您可以使用以下查询:

SELECT BANK, ACCOUNT_NAME, EXCESS, DEBT,
       CASE WHEN ROW_NUMBER() OVER (PARTITION BY BANK ORDER BY ACCOUNT_NAME) = 1 
          THEN SUM(EXCESS) OVER (PARTITION BY BANK) - 
               SUM(DEBT) OVER (PARTITION BY BANK) 
          ELSE NULL 
       END AS AVAILABLE
FROM BankBalances

您可以使用SUM的窗口版本以避免CROSS APPLYROW_NUMBER仅用于检查第一行。

我假设 first 行被认为是每个ACCOUNT_NAME分区中具有“最小”BANK值的行。

Demo here

答案 1 :(得分:1)

您可以像这样使用ROW_NUMBERSUM OVER()分区。

;WITH CTE AS 
(
SELECT
    BANK
    ,ACCOUNT_NAME
    ,EXCESS
    ,DEBT
    ,SUM(EXCESS - DEBT)  OVER(PARTITION BY BANK) AS AVAILABLE,
    ,ROW_NUMBER()OVER(PARTITION BY BANK ORDER BY ACCOUNT_NAME ASC) rn
FROM BankBalances
)
SELECT BANK
    ,ACCOUNT_NAME
    ,EXCESS
    ,DEBT
    ,CASE WHEN rn = 1 THEN AVAILABLE ELSE null end as AVAILABLE 
FROM CTE