mysql脚本-数学解决方案
我有一个16列的表: Id,产品Id,周日,周日,周一,周一,周六 如您所见,有工作日列和工作日计数列 我希望仅当“工作日计数”列的值大于零时,才平均每个星期天的值 范例mysql脚本-数学解决方案,mysql,sql,math,Mysql,Sql,Math,我有一个16列的表: Id,产品Id,周日,周日,周一,周一,周六 如您所见,有工作日列和工作日计数列 我希望仅当“工作日计数”列的值大于零时,才平均每个星期天的值 范例 Sunday=30 SundayCnt=0 Monday=27 MondayCnt=2 Tuesday=2 TuesdayCnt=0 Wednesday=75 WednesdayCnt=0 Thursday=2 ThursdayCnt=1 Friday=12 FridayCnt
Sunday=30 SundayCnt=0
Monday=27 MondayCnt=2
Tuesday=2 TuesdayCnt=0
Wednesday=75 WednesdayCnt=0
Thursday=2 ThursdayCnt=1
Friday=12 FridayCnt=0
Saturday=15 SaturdayCnt=22
对于本例,平均值必须仅取(27+2+15)/3=14.66,因为这些天的Cnt列大于0
任何关于如何在一个简单的脚本上实现这一点的想法都不会很好
SELECT id, Product_Id,
IF( denominator = 0, null, numerator / denominator) as average
FROM
(
SELECT Id, Product_Id,
(
if( SundayCnt=0, 0, Sunday) +
if( MondayCnt=0, 0, Monday) +
if( TuesdayCnt=0, 0, Tuesday) +
if( ThursdayCnt=0, 0, Wednesday) +
if( FridayCnt=0, 0, Thursday) +
if( SaturdayCnt=0, 0, Saturday)
) as numerator ,
(
if( SundayCnt=0, 0, 1) +
if( MondayCnt=0, 0, 1) +
if( TuesdayCnt=0, 0, 1) +
if( ThursdayCnt=0, 0, 1) +
if( FridayCnt=0, 0, 1) +
if( SaturdayCnt=0, 0, 1)
) as denominator
FROM YourTable
) as T
但是你应该考虑把你的表换成
ID ProductID Sales Counter Day
1 1 30 0 Sunday
2 1 27 2 Monday
3 1 2 0 Tuesday
4 1 75 0 Wednesday
5 1 2 1 Thursday
6 1 12 0 Friday
7 1 15 22 Saturday
那么你的查询就很容易了
SELECT product_id, IF(Count(*) = 0, null, SUM(Sales)/Count(*))
From YourTable
WHERE Counter <> 0
GROUP BY product_id
选择产品标识,如果(计数(*)=0,则为空,总和(销售)/计数(*)
从你的桌子上
0号柜台在哪里
按产品编号分组
这不会很漂亮
SELECT id, Product_Id,
IF( denominator = 0, null, numerator / denominator) as average
FROM
(
SELECT Id, Product_Id,
(
if( SundayCnt=0, 0, Sunday) +
if( MondayCnt=0, 0, Monday) +
if( TuesdayCnt=0, 0, Tuesday) +
if( ThursdayCnt=0, 0, Wednesday) +
if( FridayCnt=0, 0, Thursday) +
if( SaturdayCnt=0, 0, Saturday)
) as numerator ,
(
if( SundayCnt=0, 0, 1) +
if( MondayCnt=0, 0, 1) +
if( TuesdayCnt=0, 0, 1) +
if( ThursdayCnt=0, 0, 1) +
if( FridayCnt=0, 0, 1) +
if( SaturdayCnt=0, 0, 1)
) as denominator
FROM YourTable
) as T
但是你应该考虑把你的表换成
ID ProductID Sales Counter Day
1 1 30 0 Sunday
2 1 27 2 Monday
3 1 2 0 Tuesday
4 1 75 0 Wednesday
5 1 2 1 Thursday
6 1 12 0 Friday
7 1 15 22 Saturday
那么你的查询就很容易了
SELECT product_id, IF(Count(*) = 0, null, SUM(Sales)/Count(*))
From YourTable
WHERE Counter <> 0
GROUP BY product_id
选择产品标识,如果(计数(*)=0,则为空,总和(销售)/计数(*)
从你的桌子上
0号柜台在哪里
按产品编号分组
编辑:抱歉,刚才看到列是一周中的实际日期,您希望每行平均,而不是跨行平均
在这种情况下,是的,您需要对每列进行显式迭代的公式,当cnt>0时,将工作日值添加到分子,将+1添加到分母。我认为这里给出的另一个答案应该足够了,但有一点需要注意:您应该用NULLIF(…,0)来包装分母,以避免被0除的错误(在这种情况下,当所有CNT都为0时,总平均值将计算为0/NULL,这将只是NULL)
在SQL中,聚合函数(如AVG、SUM等)忽略NULL的输入。因此,只要CNT为0,就需要将NULL馈送到AVG:
AVG(CASE WHEN weekday_cnt = 0 THEN NULL ELSE weekday_val END)
编辑:抱歉,刚才看到列是一周中的实际日期,您希望每行平均,而不是跨行平均 在这种情况下,是的,您需要对每列进行显式迭代的公式,当cnt>0时,将工作日值添加到分子,将+1添加到分母。我认为这里给出的另一个答案应该足够了,但有一点需要注意:您应该用NULLIF(…,0)来包装分母,以避免被0除的错误(在这种情况下,当所有CNT都为0时,总平均值将计算为0/NULL,这将只是NULL) 在SQL中,聚合函数(如AVG、SUM等)忽略NULL的输入。因此,只要CNT为0,就需要将NULL馈送到AVG:
AVG(CASE WHEN weekday_cnt = 0 THEN NULL ELSE weekday_val END)
这是世界其他地区的平均值吗?那么对于每种产品?你想要什么类型的平均值?这是世界其他地区的平均值吗?那么对于每种产品?你想要什么类型的平均值?唯一的问题是,这不能处理被零除的情况。添加一个“if”来处理这个问题会更不美观,但这是必要的。如果所有计数都为零,这将抛出一个被零除的错误。我认为这是一个很好的选择,谢谢。我想知道是否有一个数学函数,例如,出于其他目的,我使用了pow(columnName,0)这个结果总是1。但不确定我现在面对的工作日情况是否存在数学公式。@DanBracuk好的,不必惊慌,我将div改为0。@GerardoAbdo没有公式,因为这只是一个特殊条件。若将列作为行,那个么可以使用聚合函数。不知道这是否是你的选择?但行设计会有更大的灵活性。唯一的问题是,它不能处理被零除的情况。添加一个“if”来处理这个问题会更不美观,但这是必要的。如果所有计数都为零,这将抛出一个被零除的错误。我认为这是一个很好的选择,谢谢。我想知道是否有一个数学函数,例如,出于其他目的,我使用了pow(columnName,0)这个结果总是1。但不确定我现在面对的工作日情况是否存在数学公式。@DanBracuk好的,不必惊慌,我将div改为0。@GerardoAbdo没有公式,因为这只是一个特殊条件。若将列作为行,那个么可以使用聚合函数。不知道这是否是你的选择?但行设计会使您获得更大的灵活性
正如您所看到的,有工作日列和工作日计数列
AVG用于行,不用于列我只需通过0修复div即可-NULLIF()是一个方便的函数,用于将来的引用正如您所看到的,有工作日列和工作日计数列
AVG用于行,不用于列我只需通过0修复div即可-NULLIF()是一个方便的函数,供将来参考!