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
The error I am getting is
Msg 156, Level 15, State 1, Procedure MyStoredProcedure1, Line 36 Incorrect syntax near the keyword 'union'.
But my goal here is the user inputs a year for example 2009, my first query will get all the sales made in 2009 to the same date it is was yesterday 12/23/2009, while the second query is getting 2009 totals up to dec 31 2009.
I want the columns to be side by side not in one column
If you want to show the data side by side, then you don't want to use UNION. Instead, you could use derived tables or CTE's and then join the 2 queries on SDESCR, DYYYY, Division. Looking at your queries, the only (apparent) difference is that one includes a where clause on the Booked column. We can move this where clause criteria in to the sum aggregate which should allow us to get all of the data we need in one pass through the tables. Something like this:
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
I encourage you to try this procedure. I think it will return the data you are looking for.
Edited to put Less than or equal for the Booked criteria.
Remove the first order by
, just before the union all
. For sanity, keep the column names the same. The second order by
applies to all the rows.
BTW, what you want is much closer to this. Did not test it, but based on your description this should be close.
;
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 ;
The problem here is not the UNION ALL or that the column aliases are not named the same. The problem is with the ORDER BY line just above the UNION ALL line. If you remove that line, your query will run. This won't list the data side by side like you wanted, but it will allow the query to run.
Requirements for UNION include that the data types be similar, that each SELECT
contains the same number of columns, and that the columns appear in the same order in both SELECT
s.
Edit: to answer your question in a comment: If you want to have the columns appear side by side, you have to put filler columns in both SELECTs.
Select Division, SDESCR, DYYYY,
Sum(APRICE) ASofSales,
'' AS YESales,
Sum(PARTY) AS ASofPAX,
'' AS YEPAX
... and so on, with identical columns in both SELECTS
, just some columns are empty in one SELECT
or the other.
Another edit: The column names (or aliases) don't have to be the same in both SELECTS, but using different aliases will help you to distinguish which column is which. On the aggregate fields (SUM), if you don't supply an alias, figuring out what the column represents could be tricky. If you alias the columns as you have done in your SQL, and interleave the empty string columns, I think you will get the result you seek.
精彩评论