具有不同where子句

时间:2015-10-08 18:03:28

标签: sql-server grouping aggregate-functions where-clause

我有一个名为Entries的表来管理特定单位的交易。

在条目中,有一个名为Sales Source的列,用于指定已完成的销售类型。我正在尝试创建一个表格,显示每个单位每个销售来源类型的总收入。

例如:

一个名为AB104的单位收入为8000美元,5000美元来自电话,3000美元来自传真来源。我想显示一个表格,显示同一行中每个销售类型的单位编号和金额。

我尝试了以下查询:

SELECT Unit,
       sum(MoneyIN + MoneyOUT) AS Revenue,
       sum(VolumeOUT+ VolumeIN) AS volume,
       sum(WeightOUT + WeightIN)AS weight,
       PercentageR = convert(VARCHAR,convert(MONEY,sum(MoneyIN+MoneyOUT)*100 /
                                               (SELECT sum(MoneyIN + MoneyOUT)
                                                FROM Entries)), 1) + '%',
       PercentageV = convert(VARCHAR,convert(MONEY,sum(VolumeIN+VolumeOUT)*100 /
                                               (SELECT sum(VolumeIN + VolumeOUT)
                                                FROM Entries)), 1) + '%',
       PercentageW = convert(VARCHAR,convert(MONEY,sum(WeightIN+WeightOUT)*100 /
                                               (SELECT sum(WeightIN + WeightOUT)
                                                FROM Entries)), 1) + '%',
       LinkRevenue=
  (SELECT sum(MoneyIN+MoneyOUT)
   WHERE salesSource ='Link'),
       PhoneRevenue=
  (SELECT sum(MoneyIN+MoneyOUT)
   WHERE salesSource ='Phone'),
       EmailRevenue=
  (SELECT sum(MoneyIN+MoneyOUT)
   WHERE salesSource ='Email'),
       FaxRevenue=
  (SELECT sum(MoneyIN+MoneyOUT)
   WHERE salesSource ='Fax'),
       NoneRevenue=
  (SELECT sum(MoneyIN+MoneyOUT)
   WHERE salesSource ='None')
FROM Entries
GROUP BY Unit,
         SalesSource
ORDER BY Unit 

然而,该查询的问题在于,它不会在一行中显示每个单元的不同收入类型。此查询将输出:

Unit | rev | vol | weight | % Revenue | % Weight | % Volume | $ Link |$Phone |$Email|$Fax |$None

AB104|5000$|22|15000| 17%| 10%|    15%| 0$|5000$|0$|0$|0$  

AB104|3000$|12|18000| 21%| 21%|    7%| 0$|0$|0$|3000$|0$

相反,我希望它将一行中相同单位的所有细节分组,如下所示:

Unit | rev | vol | weight | % Revenue | % Weight | % Volume | $ Link |$Phone |$Email|$Fax |$None

AB104|8000$|34|33000| 38%| 31%|    22%| 0$|5000$|0$|3000$|0$  

我怎样才能做到这一点?当我将salesSource从分组中删除时,我收到错误。

2 个答案:

答案 0 :(得分:0)

您的分组中有两列。您看到每个SalesSource都有一个Unit行。您可以单独将SalesSource添加为列,并查看。

此外,您希望避免在select子句中添加其他选择,因为您的SQL会针对每个结果运行单独的查询,在您的情况下,对每个结果进行3次查询。这将使您的查询不具有很强的可扩展性。

我认为您需要从group by子句和用例语句中删除SalesSource。

 Sum(Case when SalesSource = 'Link' then (MoneyIn+MoneyOut) else 0 end) as LinkRevenue,

您可以使用公用表表达式删除select-in-a-select:

 ;with totals as (
      SELECT sum(WeightIN + WeightOUT) as WeightTotal,
             sum(VolumeIN + VolumeOUT) as VolumeTotal,
             sum(MoneyIN + MoneyOUT) as MoneyTotal
      FROM Entries
 )
 SELECT Unit,
   sum(MoneyIN + MoneyOUT) AS Revenue,
   sum(VolumeOUT+ VolumeIN) AS volume,
   sum(WeightOUT + WeightIN)AS weight,
   PercentageR = convert(VARCHAR,convert(MONEY,sum(MoneyIN+MoneyOUT)*100 /
                                           totals.MoneyTotal), 1) + '%',
   PercentageV = convert(VARCHAR,convert(MONEY,sum(VolumeIN+VolumeOUT)*100 /
                                           totals.VolumeTotal), 1) + '%',
   PercentageW = convert(VARCHAR,convert(MONEY,sum(WeightIN+WeightOUT)*100 /
                                           totals.WeightTotal), 1) + '%',
   Sum(Case when SalesSource = 'Link' then (MoneyIn+MoneyOut) else 0 end) as LinkRevenue,
 ....
 FROM Entries, totals
 GROUP BY Unit
 ORDER BY Unit 

答案 1 :(得分:0)

您可以使用更多cte来清理它,我没有使用$符号格式化Money列,但您可以将其添加到最终选择中

With 
--create CTE with money columns summed for the pivotcte
TotalsCTEBySource (Unit, [Revenue],  SalesSource) AS
(SELECT Unit, MoneyIn+MoneyOut ,  SalesSource FROM Entries), 
--create CTE with table grand totals for % calcs
GrandTotalsCTE ([Revenue], [Volume],[Weight]) AS 
(SELECT sum(MoneyIn+MoneyOut) , sum(VolumeIn+VolumeOut) , sum(WeightIn+WeightOut) FROM Entries), 
--create totals by unit cte
TotalsCTEByUnit (Unit, [Revenue], [Volume],[Weight]) AS
(SELECT Unit, sum(MoneyIn+MoneyOut) , sum(VolumeIn+VolumeOut) , sum(WeightIn+WeightOut)
FROM Entries GROUP BY Unit), 
--create pivot cte to get the sales source values as column headers, use coalesce() to turn NULL into 0
PivotCTE (Unit, [$ Link],[$ Phone],[$ Fax],[$ Email],[$ None])AS
(   select Unit,coalesce(sum([Link]),0), coalesce(sum([Phone]),0),coalesce(sum([Fax]),0),
    coalesce(sum([Email]),0),coalesce(sum([None]),0) FROM(
    select Unit, [Link],[Phone],[Fax],[Email],[None] from TotalsCTEBySource
        PIVOT
            (sum(Revenue)FOR SalesSource in ([Link],[Phone],[Fax],[Email],[None])) pivottable 
    ) moneybygroup
group by Unit   )

--bring it all together
SELECT t.Unit, t.Revenue, t.Volume, t.Weight,
CONVERT(VARCHAR(50),round(t.Revenue/g.revenue*100,0))+' %' AS [% Revenue],
CONVERT(VARCHAR(50),round(t.Volume/g.Volume*100,0))+' %' AS [% Volume],
CONVERT(VARCHAR(50),round(t.Weight/g.Weight*100,0))+' %' AS [% Weight]
p.[$ Link],p.[$ Phone],p.[$ Fax],p.[$ Email],p.[$ None] 
FROM TotalsCTEByUnit t
Join PivotCTE p on t.unit=p.unit
join GrandTotalsCTE g on 1=1
相关问题