Question

So I am trying to create a report which will give me a count of sales orders and compare them to a previous date ranges. unfortunately I am not sure how to approach returning the results as each of these calculations are ran against the same table column.

Ideally my output would look something like this, including the NULL values

partner    Today    LastYear    TwoYear
-------    ------   --------    --------
zzz        10       15          4
yyy        2                    4
xxx        3        1           2

I have the basic idea down:

DECLARE @currentDay DATETIME
SET @currentDay =  DATEDIFF(day,0,GETDATE()) -- Gives it 00:00:00.000 for time

-- Todays orders
SELECT count(s.po_id) as 'Orders Today',c.tp_name
FROM [EDI_001].[dbo].[303v850h] as s
join [EDI_001].[dbo].[Trade] as c
on s.TP_PartID = c.TP_PartID
where s.ExportDate < @currentDay AND
      s.ExportDate > DATEADD(day,-1,@currentDay)
group by c.tp_name
order by c.tp_name;

-- Last Years Day's orders
SELECT count(s.po_id) as 'Orders Today',c.tp_name
FROM [EDI_001].[dbo].[303v850h] as s
join [EDI_001].[dbo].[Trade] as c
on s.TP_PartID = c.TP_PartID
where s.ExportDate < DATEADD(year,-1,@currentDay) AND
      s.ExportDate > DATEADD(year, -1,DATEADD(day,-1,@currentDay))
group by c.tp_name
order by c.tp_name;

I'll go ahead and stop there, as you can see the queries are almost identical just changing the date range in the where clause. What I don't know is how to combine the two queries into a single result set. As well, my join does not return the empty sets in either query. I realize that it won't with the current join used, however it hasn't shown in different results with left outer joins either... But realistically one problem at a time and the first step is to get a single result set. Any help would be greatly appreciated.

Was it helpful?

Solution

DECLARE @currentDay DATETIME
SET     @currentDay = DATEDIFF(day,0,GETDATE()) -- Gives it 00:00:00.000 for time

SELECT  Sum(
            CASE 
            WHEN s.ExportDate Between DATEADD(day,-1,@currentDay) AND @currentDay 
            THEN 1 
            ELSE 0 
            END
            ) As Today,
        Sum(
            CASE 
            WHEN s.ExportDate Between DATEADD(year, -1,DATEADD(day,-1,@currentDay)) AND DATEADD(year,-1,@currentDay) 
            THEN 1 
            ELSE 0 
            END
            ) As LastYear,
        Sum(
            CASE 
            WHEN s.ExportDate Between DATEADD(year, -2,DATEADD(day,-1,@currentDay)) AND DATEADD(year,-2,@currentDay) 
            THEN 1 
            ELSE 0 
            END
            ) As TwoYear,
        c.tp_name
FROM    [EDI_001].[dbo].[303v850h] as s
JOIN    [EDI_001].[dbo].[Trade] as c
        on  s.TP_PartID = c.TP_PartID
GROUP   BY c.tp_name
ORDER   BY c.tp_name;

OTHER TIPS

You are looking for the UNION operator. It's used to combine the result-set of two or more SELECT statements.

http://www.w3schools.com/sql/sql_union.asp

You can use a conditional aggregate:

SELECT  c.tp_name,
        Today = COUNT(CASE WHEN s.ExportDate > DATEADD(DAY,-1,@currentDay) THEN s.po_id END),
        LastYear = COUNT(CASE WHEN s.ExportDate > DATEADD(YEAR,-1,@currentDay) 
                            AND s.ExportDate < DATEADD(YEAR, -1,DATEADD(DAY, -1, @currentDay))THEN s.po_id END),
        TwoYear = COUNT(CASE WHEN s.ExportDate > DATEADD(YEAR,-2, @currentDay) 
                            AND s.ExportDate < DATEADD(YEAR, -2, DATEADD(DAY, -1, @currentDay))THEN s.po_id END),
FROM    [EDI_001].[dbo].[303v850h] as s
        JOIN [EDI_001].[dbo].[Trade] as c
            ON s.TP_PartID = c.TP_PartID
WHERE s.ExportDate < @currentDay AND
      s.ExportDate > DATEADD(YEAR, -2, DATEADD(DAY, -1, @currentDay))
GROUP BY c.tp_name
ORDER BY c.tp_name;

So you are essentially moving each of your WHERE clauses to a CASE statement inside the the COUNT, so you will only count records where your criteria is met.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top