Union All无法在存储过程中使用

时间:2010-12-23 17:19:06

标签: sql-server sql-server-2005 stored-procedures

ALTER PROCEDURE [dbo].[MyStoredProcedure1]
 @YearToGet int

AS
Select Division, SDESCR,        
    DYYYY, 
 Sum(APRICE) ASofSales, 
    Sum(PARTY) AS ASofPAX,        
    Sum(NetAmount) ASofNetSales,        
    Sum(InsAmount) ASofInsSales,        
    Sum(CancelRevenue) ASofCXSales,        
    Sum(OtherAmount) ASofOtherSales,        
    Sum(CXVALUE) ASofCXValue  
From dbo.B101BookingsDetails 
Where Booked <= CONVERT(int,DateAdd(year, @YearToGet - Year(getdate()),                   
                DateAdd(day, DateDiff(day, 1, getdate()), 0) ) ) and
(DYYYY = @YearToGet)
Group By SDESCR, DYYYY, Division
Having (DYYYY = @YearToGet)  
Order By Division, SDESCR, DYYYY 

union all

SELECT     
DIVISION, 
SDESCR,
DYYYY, 
SUM(APRICE) AS YESales, 
SUM(PARTY) AS YEPAX, 
SUM(NetAmount) AS YENetSales,
SUM(InsAmount)  AS YEInsSales, 
SUM(CancelRevenue) AS YECXSales, 
SUM(OtherAmount) AS YEOtherSales,
SUM(CXVALUE) AS YECXValue
FROM         dbo.B101BookingsDetails 
Where (DYYYY=@YearToGet)
GROUP BY SDESCR, DYYYY, DIVISION
ORDER BY DIVISION, SDESCR, DYYYY

我得到的错误是

  

Msg 156,Level 15,State 1,Procedure   MyStoredProcedure1,第36行不正确   关键字'union'附近的语法。

但我的目标是用户输入一年例如2009年,我的第一个查询将使2009年的所有销售额达到与昨天12/23/2009相同的日期,而第二个查询将获得2009年总计截至2009年12月31日。

我希望列不在一列中并排

4 个答案:

答案 0 :(得分:4)

如果要并排显示数据,则不希望使用UNION。相反,您可以使用派生表或CTE,然后在SDESCR,DYYYY,Division上加入2个查询。查看您的查询,唯一(明显的)区别是,在Booked列中包含where子句。我们可以将where子句标准移到sum聚合中,这样我们就可以在一次通过表中获得所需的所有数据。像这样:

ALTER PROCEDURE [dbo].[MyStoredProcedure1]
 @YearToGet int
AS
SET NOCOUNT ON

Declare @Booked Int
Set @Booked = CONVERT(int,DateAdd(year, @YearToGet - Year(getdate()),                   
                DateAdd(day, DateDiff(day, 1, getdate()), 0) ) )

Select Division, 
       SDESCR,        
       DYYYY, 
       Sum(Case When Booked <= @Booked Then APRICE End) ASofSales, 
       SUM(APRICE) AS YESales, 

       Sum(Case When Booked <= @Booked Then PARTY End) AS ASofPAX,        
       SUM(PARTY) AS YEPAX, 

       Sum(Case When Booked <= @Booked Then NetAmount End) ASofNetSales,        
       SUM(NetAmount) AS YENetSales,

       Sum(Case When Booked <= @Booked Then InsAmount End) ASofInsSales,        
       SUM(InsAmount)  AS YEInsSales, 

       Sum(Case When Booked <= @Booked Then CancelRevenue End) ASofCXSales,        
       SUM(CancelRevenue) AS YECXSales, 

       Sum(Case When Booked <= @Booked Then OtherAmount End) ASofOtherSales,        
       SUM(OtherAmount) AS YEOtherSales,

       Sum(Case When Booked <= @Booked Then CXVALUE End) ASofCXValue,
       SUM(CXVALUE) AS YECXValue
From   dbo.B101BookingsDetails 
Where  DYYYY = @YearToGet
Group By SDESCR, DYYYY, Division
Order By Division, SDESCR, DYYYY 

我鼓励您尝试这个程序。我认为它将返回您正在寻找的数据。

编辑为小于或等于预订标准。

答案 1 :(得分:3)

删除order by之前的第一个union all。为了理智,请保持列名相同。第二个order by适用于所有行。

BTW ,你想要的更接近这一点。没有测试它,但根据你的描述,这应该是接近的。

;
with
q_00 as (
select
      DIVISION
    , SDESCR
    , DYYYY
    , sum(APRICE)        as ofSales 
    , sum(PARTY)         as ofPAX        
    , sum(NetAmount)     as ofNetSales        
    , sum(InsAmount)     as ofInsSales        
    , sum(CancelRevenue) as ofCXSales        
    , sum(OtherAmount)   as ofOtherSales        
    , sum(CXVALUE)       as ofCXValue  
from dbo.B101BookingsDetails 
where Booked <= CONVERT(int,DateAdd(year, @YearToGet - Year(getdate()), DateAdd(day, DateDiff(day, 1, getdate()), 0)))
  and DYYYY = @YearToGet
group by DIVISION, SDESCR, DYYYY 
),
q_01 as (
select     
      DIVISION 
    , SDESCR
    , DYYYY 
    , sum(APRICE)        as YESales 
    , sum(PARTY)         as YEPAX 
    , sum(NetAmount)     as YENetSales
    , sum(InsAmount)     as YEInsSales 
    , sum(CancelRevenue) as YECXSales 
    , sum(OtherAmount)   as YEOtherSales
    , sum(CXVALUE)       as YECXValue
from  dbo.B101BookingsDetails 
where DYYYY=@YearToGet
group by DIVISION, SDESCR, DYYYY 
)
select
      a.DIVISION 
    , a.SDESCR
    , a.DYYYY
    , ofSales 
    , ofPAX        
    , ofNetSales        
    , ofInsSales        
    , ofCXSales        
    , ofOtherSales        
    , ofCXValue  
    , YESales 
    , YEPAX 
    , YENetSales
    , YEInsSales 
    , YECXSales 
    , YEOtherSales
    , YECXValue
from q_00 as a
join q_01 as b on (b.DIVISION = a.DIVISION and b.SDESCR = a.SDESCR and b.DYYYY = a.DYYYY) 
order by a.DIVISION, a.SDESCR, a.DYYYY ;

答案 2 :(得分:2)

UNION的要求包括数据类型相似,每个SELECT包含相同数量的列,并且SELECT个列中的列显示顺序相同。

编辑:在评论中回答您的问题:如果您希望将列并排显示,则必须在两个SELECT中添加填充列。

Select Division, SDESCR, DYYYY, 
Sum(APRICE) ASofSales, 
'' AS YESales,
Sum(PARTY) AS ASofPAX,  
'' AS YEPAX

...依此类推,两个SELECTS中的列相同,只有一些列在一个SELECT或另一列中为空。

另一个编辑:两个SELECTS中的列名(或别名)不必相同,但使用不同的别名可以帮助您区分哪个列。在聚合字段(SUM)上,如果您不提供别名,则确定列表示的内容可能会非常棘手。如果你像在SQL中那样对列进行别名,并交错空字符串列,我想你会得到你想要的结果。

答案 3 :(得分:2)

此处的问题不是UNION ALL,或者列别名的名称不相同。问题出在UNION ALL行上方的ORDER BY行。如果删除该行,您的查询将会运行。这不会像您想要的那样并排列出数据,但它将允许查询运行。