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

时间:2017-03-05 06:00:20

标签: sql

因此,我有一个直接的方式来获得日期范围的前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

现在我想要的是另外两列显示SoldQty和SalesCount在相同日期范围之前或前一年等30天。我试图避免循环或多次访问服务器(如果可能)。

我当时认为这将是某种形式:

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

但我想不出如何使用在IN子句中创建的集合来获取我需要的其他数据。

我认为可能有用的另一种方式是可以像这样引用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

正确方向的任何一点都会很好。

1 个答案:

答案 0 :(得分:2)

考虑派生表,其中第一个聚合查询检索前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

或者,您可以使用表别名为相关子查询稍微调整第二个查询。但是,由于每个行都运行子查询而不是所有行的一次调用

,因此效率稍低
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