比在同一个表中的LEFT JOIN上包含空行更有效的方法?

时间:2018-12-02 04:43:39

标签: mysql

请考虑下表:

 ____________________________________
|          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 < / p>

此查询可获取正确的总和分组,但不包含空组合的0值:

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

结合使用LEFT JOINIFNULL(<condition>,0)

可以得到正确的结果。

我的数据集上的第一次查询平均为0.22秒。 LEFT JOIN / IFNULL查询平均为0.98秒。是否有一个查询结构将包含0值,并且执行时间接近第一次查询的0.22s?我的脚本每次调用可能会运行该查询数千次。

这实际上是外部查询的子查询,用于计算stdev_samp()的{​​{1}},因此,我确实需要包含0个值。

2 个答案:

答案 0 :(得分:0)

如果没有明显的数据可以测试和比较,我将提供以下内容。内部查询遍历列表ONCE并进行总和,因为val_4 = 1且当= 0时,这是与分组有关的各个单独列的结果。完成此操作后,所有组合均已由group by解析。因此,现在外部查询获取Val 1和Val 2,但最终查询为大小写。如果SumWhen1> 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

现在,如果您的数据可以包含负数,那么我将在内部查询中添加以下内容,并以此列为基础来确认val_4是否有任何记录。

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

答案 1 :(得分:0)

我们可以进行条件聚合,而无需使用任何派生表(子查询)或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   |

结果

{{1}}

View on DB Fiddle