Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
mysql脚本-数学解决方案_Mysql_Sql_Math - Fatal编程技术网

mysql脚本-数学解决方案

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

我有一个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=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()是一个方便的函数,供将来参考!