简体   繁体   English

在SQL中如何获取两组日期范围的求和

[英]In SQL How can I get Sums for two sets of date ranges

So I have this as a straight forward way to get the top 10 selling items for a date range: 因此,我将其作为获取日期范围内销售量最高的10种商品的直接方法:

SELECT TOP 10 Sku, Title, SUM(Qty) as SoldQty, COUNT(Qty) as SalesCount
FROM Sales
WHERE SaleDate BETWEEN @StartDate AND @EndDate
GROUP BY Sku, Title
ORDER BY SUM(Qty) DESC

Now what I want is two more columns that show SoldQty and SalesCount for same date range 30 days prior or the previous year etc. I am trying to avoid loops or multiple trips to the server if possible. 现在,我想要的是另外两列,分别显示前30天或上一年等日期的相同日期范围内的SoldQty和SalesCount等。如果可能,我试图避免出现循环或多次访问服务器的情况。

I was thinking it would be some form of this: 我以为这是某种形式:

SELECT TOP 10 Sku, Title, SUM(Qty) as SoldQty, COUNT(Qty) as SalesCount
FROM Sales
WHERE Sku IN
(
    SELECT TOP 10 Sku
    FROM Sales
    WHERE SaleDate BETWEEN @StartDate AND @EndDate
    GROUP BY Sku
    ORDER BY SUM(Qty) DESC
)
AND SaleDate BETWEEN @StartDate AND @EndDate
GROUP BY Sku, Title
ORDER BY SUM(Qty) DESC

But I can't think of how to use that set created in the IN clause to get the other data I need. 但是我想不起来如何使用IN子句中创建的那个集合来获取我需要的其他数据。

Another way I was thinking might work was where the Sku can be referenced like this: 我认为可能可行的另一种方式是可以在Sku中这样引用:

SELECT TOP 10 Sku as TopSku, Title, SUM(Qty) as SoldQty, COUNT(Qty) as SalesCount,
(
    SELECT SUM(Qty)
    FROM Sales
    WHERE Sku = TopSku
    AND SaleDate BETWEEN DATEADD(DAY, -30, @StartDate) AND DATEADD(DAY, -30, @EndDate)
) as PrevSoldQty,
(
    SELECT Count(Qty)
    FROM Sales
    WHERE Sku = TopSku
    AND SaleDate BETWEEN DATEADD(DAY, -30, @StartDate) AND DATEADD(DAY, -30, @EndDate)
) as PrevSalesCount

FROM Sales
WHERE SaleDate BETWEEN @StartDate AND @EndDate
GROUP BY Sku, Title
ORDER BY SUM(Qty) DESC

Any point in the right direction would be nice. 朝正确方向的任何一点都将是不错的。

Consider derived tables where first aggregate query retrieves top 10 SKUs and second aggregate query matches those same SKUs for previous date range: 考虑派生表,其中第一个聚合查询检索前10个SKU,第二个聚合查询与先前日期范围内的相同SKU匹配:

SELECT s.Sku, s.Title, s.SoldQty, s.SalesCount, p.PrevSoldQty, p.PrevSalesCount
FROM
(
    SELECT TOP 10 Sku, Title, SUM(Qty) As SoldQty, COUNT(Qty) As SalesCount
    FROM Sales
    WHERE SaleDate BETWEEN @StartDate AND @EndDate
    GROUP BY Sku, Title
    ORDER BY SUM(Qty) DESC
) As s
INNER JOIN
(
    SELECT Sku, Title, SUM(Qty) As PrevSoldQty, COUNT(Qty) As PrevSalesCount
    FROM Sales
    WHERE SaleDate BETWEEN DATEADD(DAY, -30, @StartDate) AND DATEADD(DAY, -30, @EndDate)
    GROUP BY Sku, Title
) As p
ON s.Sku = p.Sku AND s.Title = p.Title

Alternatively, you can adjust second query slightly for correlated subqueries using table aliases. 或者,您可以使用表别名对相关子查询略微调整第二个查询。 However, this is slightly less efficient since subqueries are run for every row and not in one call across all rows 但是,由于子查询是针对每一行运行的,而不是针对所有行的一次调用,因此效率略低

SELECT TOP 10 s.Sku, s.Title, SUM(s.Qty) as SoldQty, COUNT(s.Qty) as SalesCount,
(
    SELECT SUM(sub.Qty)
    FROM Sales sub
    WHERE sub.Sku = s.Sku
    AND sub.SaleDate BETWEEN DATEADD(DAY, -30, @StartDate) AND DATEADD(DAY, -30, @EndDate)
) as PrevSoldQty,
(
    SELECT Count(sub.Qty)
    FROM Sales sub
    WHERE sub.Sku = s.Sku
    AND sub.SaleDate BETWEEN DATEADD(DAY, -30, @StartDate) AND DATEADD(DAY, -30, @EndDate)
) as PrevSalesCount

FROM Sales s
WHERE s.SaleDate BETWEEN @StartDate AND @EndDate
GROUP BY s.Sku, s.Title
ORDER BY SUM(s.Qty) DESC

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM