2011-03-25 112 views
1

我有以下三个查询可以得到三个特定时间段内产品的平均价格:所有数据,最近7天和最近30天。三个时期的计算平均值

SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
FROM dbo.Products 
WHERE Id = @id 

SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
FROM dbo.Products 
WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 7 

SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
FROM dbo.Products 
WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 30 

这三个查询给我正确的数据,但不是我想要的形式。有没有办法将这三个查询合并为一个。我的最终目标是创建一个包含所有这些数据的视图。

此外,在我看来,7天计算的平均值可以重复使用30天和所有列表。有我可以做的优化吗?

回答

1

这样的事情。确保正确测试

SELECT 
     AVG(Price) AS AggregatedPrice 
    , COUNT(*) AS PCount 
    , AVG(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 7 THEN Price ELSE Null End) AS AggregatedPrice7Days 
    , SUM(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 7 THEN 1 ELSE 0 End) AS AggregatedPrice7Days 
    , AVG(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 30 THEN Price ELSE Null End) AS AggregatedPrice30Days 
    , SUM(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 30 THEN 1 ELSE 0 End) AS AggregatedPrice30Days 
FROM 
    dbo.Products 
WHERE 
    Id = @id 
+0

太棒了!我看了这个执行计划,它比3次选择要快。 – Martin 2011-03-25 16:52:13

2
SELECT @Id 
     , t1.AggregatedPrice AggregatedPrice_ALL, t1.PCount PCount_ALL 
     , t2.AggregatedPrice AggregatedPrice_7, t2.PCount PCount_7 
     , t3.AggregatedPrice AggregatedPrice_30, t3.PCount PCount_30 
FROM 
    (SELECT Id, AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
    FROM dbo.Products 
    WHERE Id = @id) t1 
    JOIN 
    (SELECT Id, AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
    FROM dbo.ApplicationPrice 
    WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 7) t2 
    ON t1.Id = t2.id 
    JOIN 
    (SELECT Id, AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount 
    FROM dbo.ApplicationPrice 
    WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 30) t3 
    ON t1.Id = t3.id 
1

我没有T-SQL得心应手测试语法,但它应该是这样的:

SELECT t1.AggregatedPrice, t1.PCount, t2.AggregatedPrice, t2.PCount, t3.AggregatedPrice, t3.PCount 
FROM 
    (SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount FROM dbo.Products WHERE Id = @id) t1, 
    (SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount FROM dbo.Products WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 7) t2, 
    (SELECT AVG(Price) AS AggregatedPrice, COUNT(*) AS PCount FROM dbo.Products WHERE Id = @id AND DATEDIFF(day, UpdatedDatetime, getdate()) < 30) t3 
1

试试这个:

SELECT AVG(Price) AS AggregatedPrice, 
     COUNT(*) AS PCount, 
     AVG(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 7 THEN Price ELSE NULL END) AS AggregatedWeekPrice, 
     COUNT(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 7 THEN 1 ELSE NULL END) AS PWeekCount, 
     AVG(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 30 THEN Price ELSE NULL END) AS AggregatedMonthPrice, 
     COUNT(CASE WHEN DATEDIFF(day, UpdatedDatetime, getdate()) < 30 THEN 1 ELSE NULL END) AS PMonthCount, 
FROM dbo.Products 
WHERE Id = @id