我有一个奇怪的问题
我有一个包含product_id,sales和day
列的表格并非所有产品每天都有销售。我想获得每个产品在过去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 :(得分: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 Server特定的,您必须将其替换为日期差异功能的服务器语法。
要获得产品销售的最后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;
这假设sales_date是日期,而不是日期时间。如果字段是日期时间,则必须提取日期部分。
最后一个窗口函数免费版本:
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被认为是日期,而不是日期时间。如果您的服务器没有支持TOP,请使用其他限制语法。
答案 1 :(得分: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,这可能不是很有效,但它应该在理论上有效。
答案 2 :(得分:0)
我不确定我是否做得对,但如果你想获得过去10天产品的平均销售量,你可以按照以下步骤进行:
SELECT Product_Id,Sum(Sales)/Count(*) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>=@Date) table GROUP BY Product_id HAVING Count(*)>0
或者您可以使用更容易的AVG Aggregate功能:
SELECT Product_Id,AVG(Sales) FROM (SELECT ProductId,Sales FROM Table WHERE SaleDAte>=@Date) table GROUP BY Product_id
<强>更新强>
现在我得到了你的意思,据我所知,在一个查询中不可能这样做。如果我们可以做这样的事情(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
但你不能在子查询中使用order by,除非你使用不适合这种情况的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
答案 3 :(得分:0)
如果这是一个销售交易表,那么在没有销售的日子里就不应该有任何行。即,如果ProductId 21在6月1日没有销售,那么这个表不应该有任何行productId = 21和day ='1 June'...因此你不应该过滤任何东西 - 不应该有任何东西到过滤掉
Select ProductId, Avg(Sales) AvgSales
From Table
Group By ProductId
应该可以正常工作。所以,如果不是,那么你没有完全或准确地解释问题。
此外,在您的问题中,您在示例SQL查询中显示平均值(销售额),但在文本中您提到“每个产品的平均销售数量......”您是否需要平均销售额或平均值销售交易数量?您是否希望仅按产品的平均值(即每种产品报告一个输出值)或者您是否想要每天每件产品的平均值?
如果您想要单独使用每件产品的平均值,那么在此之前的十天内只需销售一次?或每件产品最后一次销售日期前十天? 如果后者那么
Select ProductId, Avg(Sales) AvgSales
From Table T
Where day > (Select Max(Day) - 10
From Table
Where ProductId = T.ProductID)
Group By ProductId
如果您想要单独的每件产品的平均值,对于每个产品的最后一次销售日期之前的十天 销售 的那些销售,那么< / p>
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