我有一个看起来像这样的表:
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
答案 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 APPLY
。 ROW_NUMBER
仅用于检查第一行。
我假设 first 行被认为是每个ACCOUNT_NAME
分区中具有“最小”BANK
值的行。
答案 1 :(得分:1)
您可以像这样使用ROW_NUMBER
和SUM 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