Mysql 按字段分组,但如果为空,则按另一字段分组

Mysql 按字段分组,但如果为空,则按另一字段分组,mysql,group-by,Mysql,Group By,我有一个表,其中有一列名为tableNum,另一列名为deviceNum 我想按tableNum分组,但如果tableNum为空,则需要按deviceNum分组 我现在已经用一个工会声明来做了,这样我就可以做两个不同的声明,但是我想知道是否有更好的方法 非常感谢 Dave您可以通过coalesce/ifnull进行分组(在本例中它们是相同的): 请参阅文档: 如果tableNum和deviceNum的值相同,那么这两列之间可能存在一些无意义的分组冲突。根据您想要得到的结果类型,您可以编写如下内

我有一个表,其中有一列名为tableNum,另一列名为deviceNum

我想按tableNum分组,但如果tableNum为空,则需要按deviceNum分组

我现在已经用一个工会声明来做了,这样我就可以做两个不同的声明,但是我想知道是否有更好的方法

非常感谢


Dave

您可以通过coalesce/ifnull进行分组(在本例中它们是相同的):

请参阅文档:

如果tableNum和deviceNum的值相同,那么这两列之间可能存在一些无意义的分组冲突。根据您想要得到的结果类型,您可以编写如下内容,以避免冲突:

GROUP BY CASE WHEN tableNum IS NOT NULL 
              THEN CONCAT('tableNum : ', tableNum)
              ELSE CONCAT('deviceNum : ', deviceNum)
              END
不过,这可能会非常慢,就像使用
CONCAT
一样,不可能使用索引。。。只是给你一个想法。注意:正如前面提到的,
UNION
的速度更快,因为MySQL可以并行子查询

尝试以下方法:

SELECT ...
FROM your_table
GROUP BY
  CASE
    WHEN tableNum IS NOT NULL THEN tableNum
    ELSE deviceNum
  END

保留
联合体
,并按照您的要求使用
联合体所有人

它可能比其他解决方案快得多(或者可以优化以运行)

我不想在没有
联合的情况下翻译或优化它:

    SELECT tableNum
         , NULL AS deviceNum
         , COUNT(DISTINCT deviceNum) AS cnt
    FROM TableX
    WHERE tableNum IS NOT NULL
    GROUP BY tableNum 
UNION ALL
    SELECT NULL
         , deviceNum
         , COUNT(*)
    FROM TableX
    WHERE tableNum IS NULL
    GROUP BY deviceNum

GROUP BY(IFNULL(child\u id,parent\u id))

尝试使用而不是GROUP BY。在这种情况下,在GROUP BY中也可以使用大小写clause@Lucas,除了并行化之外,如果没有联合,他还必须在选择列表中的几乎所有字段中使用
CASE
。和按大小写分组可能不使用索引。@ypercube:True。但是通过
IFNULL(…)
进行选择和分组并不像使用
CASE
子句那样糟糕…@Lucas:你说得对。如果有可能使用索引,可以使用
IFNULL()
COALESCE()
CONCAT()
肯定会使它进入完全扫描。@ypercube:True。我会将此添加到解释中请提供更多详细信息,而不是在没有任何说明的情况下删除一段简短的代码
    SELECT tableNum
         , NULL AS deviceNum
         , COUNT(DISTINCT deviceNum) AS cnt
    FROM TableX
    WHERE tableNum IS NOT NULL
    GROUP BY tableNum 
UNION ALL
    SELECT NULL
         , deviceNum
         , COUNT(*)
    FROM TableX
    WHERE tableNum IS NULL
    GROUP BY deviceNum