2009-09-17 53 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