将行与单个SQL Server表中的其他行进行比较

时间:2016-12-20 03:43:41

标签: sql sql-server sql-server-2008

我有一张包含以下数据行的表格。

EngID   Tower   Billing  Amt
100     ICS       Y      5000
100     EDT       Y      7777
100     ICS       N      2000

我希望结果集由Tower& amp; Eng ID和根据出具标准输入相应列(已开票或未开票)的金额。因此,下面是最终结果集应如何查找上表:

EngID  Tower   Inv Amt (Amt when Billing = Y)  Non-Invoiced Amt (Billing=N)
100     ICS       5000                                     2000
100     EDT       7777

我可以使用以下查询获取结果集的第一行:

Select Temp1.Tower, Temp1. EngID, Temp2.InvoiceAmt as [Inv Amt], Temp1.InvoiceAmt AS [Non-Invoiced Amt] from
(
SELECT EngID, TOWER,BILLING, InvoiceAmt,RANK() OVER (PARTITION BY EngID, TOWER ORDER BY BILLING) AS RNK
  FROM [GDF].[dbo].[Sample]  ) Temp1 INNER JOIN (SELECT EngID, TOWER,Billing,InvoiceAmt, RANK() OVER (PARTITION BY EngID, TOWER ORDER BY BILLING) AS RNK
  FROM [GDF].[dbo].[Sample] ) Temp2 ON 

  Temp1.EngID = Temp2.EngID
  AND (Temp1.Tower = Temp2.Tower AND Temp1.Billing < Temp2.Billing) 

然而,努力获得第二排结果。我的计划是通过两个单独的查询获得两行,然后执行联合以组合结果。

4 个答案:

答案 0 :(得分:2)

一种方法是条件聚合:

select s.engid, s.tower,
       sum(case when s.billing = 'Y' then amt end) as billing_y,
       sum(case when s.billing = 'N' then amt end) as billing_n
from gdf.dbo.sample s
group by s.engid, s.tower;

答案 1 :(得分:1)

试试这个:

select engid, tower,
    sum(case when billing = 'Y' then amt end) Inv_amt,
    sum(case when billing = 'N' then amt end) Non_Inv_amt,
from my_table
group by
    engid,
    tower;

答案 2 :(得分:0)

我们也可以使用OUTER APPLY执行此操作,如下所示:

if(-not [console]::NumberLock){ 
    $w = New-Object -ComObject WScript.Shell; 
    $w.SendKeys('{NUMLOCK}'); 
}

简单LEFT JOIN:

select A.EngID, 
    sum(A.Amt) as [Inv Amt (Amt when Billing = Y)], 
    sum(B.Amt) as [Non-Invoiced Amt (Billing=N)]
from #test A
outer apply(select b.Amt from #test B where A.EngID = b.EngID and b.tower = a.tower and B.Billing = 'n') B
where a.billing = 'y'
group by A.EngID, A.Tower

答案 3 :(得分:0)

此代码将提供所需的结果,没有任何复杂性。请从下面提到的查询中找到输出的快照。希望我解决了您的问题。 enter image description here

WITH Mycte
AS
(
Select ENGID,Tower,Case When Billing='Y' Then  ISNULL(SUM(Amt),0) END AS Inv_Amt,
Case When Billing='N' Then ISNULL(SUM(Amt),0) END AS Non_Inv_Amt from #Sample
group by ENGID,Tower,Billing
)
Select ENGID,Tower,SUM(Inv_Amt) AS Inv_Amt,SUM(Non_Inv_Amt) AS Non_Inv_Amt from mycte
group by ENGID,Tower