2009-09-17 28 views
1

我有一个奇怪的问题我能否限制使用一组在GROUP BY语句

我有一个表中的列PRODUCT_ID,行的销售金额和日期

并非所有产品每天都有销售。我想获得销售的平均数量是每个产品曾在最近10天在那里有销售

通常我会得到平均这样

SELECT product_id, AVG(sales) 
FROM table 
GROUP BY product_id 

有没有办法来限制每个产品需要考虑的行数?

恐怕这是不可能的,但我想,以检查是否有人有一个想法

更新澄清:

产品可在天1,3,5,10,15,17出售20。 因为我不希望得到一个平均的所有天,但仅天平均在产品没有真正得到卖给做这样的事情

SELECT product_id, AVG(sales) 
FROM table 
WHERE day > '01/01/2009' 
GROUP BY product_id 

将无法​​正常工作

回答

0

给这旋转。子查询选择销售产品的最后十天,外部查询进行聚合。

SELECT t1.product_id, SUM(t1.sales)/COUNT(t1.*) 
FROM table t1 
    INNER JOIN (
       SELECT TOP 10 day, Product_ID 
       FROM table t2 
       WHERE (t2.product_ID=t1.Product_ID) 
       ORDER BY DAY DESC 
       ) 
    ON (t2.day=t1.day) 

GROUP BY t1.product_id 

BTW:此方法使用correlated subquery,这可能不是很高性能的,但它应该在理论工作。

+0

不完全...它必须是销售发生的每个组中的最后10天。 – 2009-09-17 21:22:34

+0

这当然会工作,如果产品被售出汽车无,但 产品可能被出售只在天1,3,4,5,10,13,20 ,如果我这样做 哪天>“9/7/2009' 我不会得到最后10天它有销售,但只是最后10天的一般。 我希望澄清一下 – MarcS 2009-09-17 21:23:21

+0

哦,好的。我现在明白了。让我看看我是否可以重新查询。这绝对是可行的。我会在几分钟内更新我的答案。 首先还有一个问题,是否可以在表格的同一天有两行产品? – JohnFx 2009-09-17 21:25:25

0

我不知道如果我得到正确的,但如果你想获得销售最近10天的平均值为你的产品,你可以做如下:

SELECT Product_Id,Sum(Sales)/Count(*) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>[email protected]) table GROUP BY Product_id HAVING Count(*)>0 

,或者您可以使用AVG聚合函数,它是更容易:

SELECT Product_Id,AVG(Sales) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>[email protected]) table GROUP BY Product_id 

更新

现在,我得到了你的意思,据我知道这是不可能做这在一个query.It可能是可能的,如果我们可以做这样的事情(Northwind数据库):

select a.CustomerId,count(a.OrderId) 
from Orders a INNER JOIN(SELECT CustomerId,OrderDate FROM Orders Order By OrderDate) AS b ON a.CustomerId=b.CustomerId GROUP BY a.CustomerId Having count(a.OrderId)<10 

而是由子查询,除非你使用TOP这是不适合这种情况下,你不能使用顺序。但是,也许你可以如下做到这一点:

SELECT PorductId,Sales INTO #temp FROM table Order By Day 

    select a.ProductId,Sum(a.Sales) /Count(a.Sales) 
    from table a INNER JOIN #temp AS b ON a.ProductId=b.ProductId GROUP BY a.ProductId Having count(a.Sales)<=10 
+0

我不知道你在使用MySql #temp是SQL Server中临时表的表示法.MySql也有临时表,但我不知道语法 – Beatles1692 2009-09-17 22:08:07

1

如果你想在过去的10个日历日,因为产品有售:

SELECT product_id, AVG(sales) 
FROM table t 
JOIN (
    SELECT product_id, MAX(sales_date) as max_sales_date 
    FROM table 
    GROUP BY product_id 
) t_max ON t.product_id = t_max.product_id 
    AND DATEDIFF(day, t.sales_date, t_max.max_sales_date) < 10 
GROUP BY product_id; 

日期不同的是SQL服务器特定的,你必须代替它与您的服务器语法的日期差异函数。

要获得最近10天,当产品有任何出售:

SELECT product_id, AVG(sales) 
FROM (
    SELECT product_id, sales, DENSE_RANK() OVER 
      (PARTITION BY product_id ORDER BY sales_date DESC) AS rn 
    FROM Table 
) As t_rn 
WHERE rn <= 10 
GROUP BY product_id; 

这asumes sales_date是一个日期,而不是日期时间。如果该字段是日期时间,则必须提取日期部分。

而且finaly一窗口免费版本:

SELECT product_id, AVG(sales) 
FROM Table t 
WHERE sales_date IN (
SELECT TOP(10) sales_date 
FROM Table s 
WHERE t.product_id = s.product_id 
ORDER BY sales_date DESC) 
GROUP BY product_id; 

再次,sales_date被asumed是日期,而不是日期时间。如果TOP未被服务器支持,请使用其他限制语法。

0

如果这是销售交易表格,那么在没有销售的日子里不应该有任何行。也就是说,如果ProductId 21在6月1日没有销售,那么这张表不应该有productId = 21和day ='1 June'的行...因此,您不应该过滤任何东西 - 不应该有任何东西过滤掉

Select ProductId, Avg(Sales) AvgSales 
From Table 
Group By ProductId 

应该可以正常工作。所以如果不是,那么你还没有完全或准确地解释问题。

另外,在年度问题中,您将在示例SQL查询中显示Avg(Sales),但在文中您提到“每个产品的平均销售数量...”您是否想要平均销售额或销售交易的平均数量?您是否希望仅通过产品计算平均值(即每个产品报告一个产出值),还是您希望每个产品每天的平均值?

如果你想要每个产品的平均水平,仅仅是在现在之前十天的销售量?或每个产品上次销售日期前十天? 如果是后者则

Select ProductId, Avg(Sales) AvgSales 
From Table T 
Where day > (Select Max(Day) - 10 
      From Table 
      Where ProductId = T.ProductID) 
Group By ProductId 

如果你想每个产品的平均独自一人,只是在这十几天的销售销售前的最后一次销售的每个产品的日期,然后

Select ProductId, Avg(Sales) AvgSales 
From Table T 
Where (Select Count(Distinct day) From Table 
     Where ProductId = T.ProductID 
      And Day > T.Day) <= 10 
Group By ProductId