Reputation: 195
I'm struggling to figure out the best way to write this query to use less queries if possible.. I'm wondering if a pivot table might be the correct way?
My 3 separate queries:
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 10 AND GETDATE() - 3) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 17 AND GETDATE() - 10) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 374 AND GETDATE() - 367) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
This produces results similar to this (first query):
UnitsSold Description
4154 desc1
764 desc2
etc..
Things to think about, a description (product group) might not exist in one of the queries so I need to account for that.
Ideally I'd like it to look a little something like this:
Description UnitsSoldThisWeek UnitsSoldLastWeek UnitsSoldLastYear
Desc1 54 45 37
etc..
Any questions, issues or bitching due to bad query is acceptable, I'm happy to improve my understanding of SQL.
Thanks,
Michael
Upvotes: 1
Views: 85
Reputation: 8865
;WITH CTE AS (
Select [UnitsSoldThisWeek],[UnitsSoldLastWeek],[UnitsSoldLastYear] FROM (
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 10 AND GETDATE() - 3) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
UNION ALL
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 17 AND GETDATE() - 10) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
UNION ALL
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
WHERE (ps.OrderDate BETWEEN GETDATE() - 374 AND GETDATE() - 367) AND ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
)
PIVOT(MAX(UnitsSold)FOR Description IN([UnitsSoldThisWeek],[UnitsSoldLastWeek],[UnitsSoldLastYear])) )
)
Select [UnitsSoldThisWeek],[UnitsSoldLastWeek],[UnitsSoldLastYear] from CTE
i am not quite sure because lack of data but we can proceed like this also
Upvotes: 1
Reputation: 1269443
Do this with one query and conditional aggregation:
SELECT coalesce(pg.[Description], 'Other') AS [Description],
sum(case when ps.OrderDate BETWEEN GETDATE() - 10 AND GETDATE() - 3 then UnitsSold
end) as ThisWeek
sum(case when ps.OrderDate BETWEEN GETDATE() - 17 AND GETDATE() - 10 then UnitsSold
else 0
end) as LastWeek,
sum(case when ps.OrderDate BETWEEN GETDATE() - 374 AND GETDATE() - 367 then UnitsSold
else 0
end) as LastYear
FROM dbo.ProductSales ps LEFT OUTER JOIN
dbo.Product p
ON ps.ProductID = p.ProductID LEFT OUTER JOIN
dbo.ProductGroupings pg
ON p.[Asin] = pg.[Asin]
WHERE ps.DistributionCentreID IN (3)
GROUP BY pg.[Description], ps.DistributionCentreID
Upvotes: 2
Reputation: 5307
i've changed your query a little to show a different technique which will combine your 3 queries. I may not have the brackets quite right round the SUMS but that gives you an idea. There are also better ways to do the sort of "date between" stuff you are trying, but that wasn't the question! See if that helps
SELECT
ISNULL(SUM(ps.UnitsSold), 0) AS UnitsSold,
ISNULL(pg.[Description], 'Other') AS [Description]
SUM(CASE WHEN (ps.OrderDate BETWEEN GETDATE() - 10 AND GETDATE() - 3) AND ps.DistributionCentreID = 3 THEN 1 ELSE 0 END) AS UnitsSoldThisWeek
SUM(CASE WHEN (ps.OrderDate BETWEEN GETDATE() - 17 AND GETDATE() - 10) AND ps.DistributionCentreID = 3 THEN 1 ELSE 0 END) AS UnitsSoldThisWeek
SUM(CASE WHEN (ps.OrderDate BETWEEN GETDATE() - 374 AND GETDATE() - 367) AND ps.DistributionCentreID = 3 THEN 1 ELSE 0 END) AS UnitsSoldThisWeek
FROM dbo.ProductSales ps
LEFT OUTER JOIN dbo.Product p ON ps.ProductID = p.ProductID
LEFT OUTER JOIN dbo.ProductGroupings pg ON p.[Asin] = pg.[Asin]
GROUP BY pg.[Description], ps.DistributionCentreID
Upvotes: 1