在mysql中,在同一个表上包含空行比左连接更有效吗?

w7t8yxp5  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(341)

考虑下表:

____________________________________
|          my_table                  |  
| ID | val_1 | val_2 | val_3 | val_4 |  
| 1  |   1   |   1   |   2   |   0   |
| 2  |   1   |   2   |   8   |   1   |
| 3  |   1   |   2   |   9   |   1   |  
| 4  |   1   |   2   |   10  |   1   |  
| 5  |   1   |   3   |   6   |   1   |  
| 6  |   1   |   4   |   8   |   1   |  
| 7  |   2   |   1   |   14  |   1   |  
| 8  |   2   |   2   |   1   |   0   |  
| 8  |   2   |   2   |   8   |   1   |  
| 8  |   2   |   3   |   2   |   0   |  
 ------------------------------------

我需要 sum(val_3) 每一种 val_1,val_2 哪里 val_4=1 ,或 0 如果没有 val_4=1 对于给定的 val_1,val_2 此查询获取正确的总和分组,但不包括 0 空组合的值:

select val_1,val_2,sum(val_3) from my_table where val_4 = 1 group by val_1,val_2

我可以得到正确的结果与组合 LEFT JOIN 在同一张table上 IFNULL(<condition>,0) 在我的数据集上,第一个查询的平均时间是0.22秒。这个 LEFT JOIN / IFNULL 查询平均0.98秒。是否有包含 0 值并执行更接近于第一次查询的0.22秒时间的操作?我的脚本每次调用可能会运行此查询几千次。
这实际上是计算 stdev_samp()val_3 ,所以我需要包含0个值。

ee7vknir

ee7vknir1#

我们可以在不使用任何派生表(子查询)的情况下进行条件聚合,或者 Left Join .
查询

SELECT
  val_1,
  val_2, 
  SUM(CASE WHEN val_4 = 1 THEN val_3
           ELSE 0 
      END) AS sum 
FROM my_table 
GROUP BY val_1, val_2;

结果

| val_1 | val_2 | sum |
| ----- | ----- | --- |
| 1     | 1     | 0   |
| 1     | 2     | 27  |
| 1     | 3     | 6   |
| 1     | 4     | 8   |
| 2     | 1     | 14  |
| 2     | 2     | 8   |
| 2     | 3     | 0   |

db fiddle视图

i7uq4tfw

i7uq4tfw2#

没有你明显的数据进行测试和比较,我提供以下。内部查询遍历该列表一次,并将valu 4=1和when=0作为分组的各个列结果进行求和。完成此操作后,所有组合都已通过group by解析。所以现在外部查询得到val1和val2,但是对于final是一个case。如果sumn1>0时有一个值,我们就知道有一个值是1。如果没有值,则返回sumwhen0结果。

SELECT
      pq.Val_1,
      pq.Val_2,
      CASE when PQ.SumWhen1 > 0 then SumWhen1 else SumWhen0 end FinalSum
   from
      ( select 
              val_1,
              val_2,
              sum( CASE when val_4 = 1 then val_2 else 0 end ) SumWhen1,
              sum( CASE when val_4 = 0 then val_2 else 0 end ) SumWhen0,
           from 
              my_table 
           where 
              val_4 = 1 
           group by 
              val_1,
              val_2 ) PQ

现在,如果您的数据可以包含负数,我只需在内部查询中添加以下内容,并使用此列作为基础来确认valu 4是否有任何记录。

sum( CASE when val_4 = 1 then 1 else 0 end ) Val1Records,

相关问题