MySQL生成一个出现在多个列中的名称列表,按字母顺序分组

时间:2014-08-06 22:29:07

标签: mysql join distinct union temporary

我需要创建一个记录摘要,这些记录按表中的名称分组。问题是,我的表有两列名称,同一列可以在任一列中。摘要应列出所有名称及其存在的记录,无论哪一列。

我可以看到这样做,首先从两列生成一个唯一的名称列表,然后扫描结果以查看名称是否出现在任一列中。我想知道MySQL是否可以在一个查询中执行此操作。

示例,这是我的表:

Id ColumnA Column B
 1   Bill    NULL
 2   NULL    Dennis
 3   Adam    Carl
 4   NULL    Adam
 5   Adam    Bill
 6   Dennis  NULL
 7   Frank   Bill

查询结果(NULL排序到顶部)

NULL    4  NULL    Adam
NULL    1  Bill    NULL
NULL    2  NULL    Dennis
NULL    6  Dennis  NULL
Adam    5  Adam    Bill
Adam    7  Adam    Carl
Bill    1  Bill    NULL
Bill    5  Adam    Bill
Bill    6  Frank   Bill
Carl    3  Adam    Carl
Dennis  2  NULL    Dennis
Dennis  6  Dennis  NULL
Frank   7  Frank   Bill

如果我可以消除列表顶部的NULL条目,那将是很好的。我只把它们放在那里因为我到目前为止尝试的所有内容都将它们放在顶部。我的结果看起来像这样:

Adam    5  Adam    Bill
Adam    7  Adam    Carl
Bill    1  Bill    NULL
Bill    5  Adam    Bill
Bill    6  Frank   Bill
Carl    3  Adam    Carl
Dennis  2  NULL    Dennis
Dennis  6  Dennis  NULL
Frank   7  Frank   Bill

2 个答案:

答案 0 :(得分:1)

您需要ID, ColumnAID, ColumnB的联合,然后汇总并订购结果。

http://sqlfiddle.com/#!2/eeec6/5/0一样:

SELECT name, GROUP_CONCAT(DISTINCT id ORDER BY id) AS ids
  FROM (
        SELECT id, a AS name
          FROM names
         UNION 
        SELECT id, b AS name
          FROM names
        ) AS t
 WHERE name IS NOT NULL
 GROUP BY name
 ORDER BY name

这将为每个名称提供一行,其中包含包含该名称的ID(行号)列表。

或者您可以一次只显示一个名称,id列(http://sqlfiddle.com/#!2/eeec6/6/0):

SELECT name, id
  FROM (
        SELECT id, a AS name
          FROM names
         UNION 
        SELECT id, b AS name
          FROM names
        ) AS t
 WHERE name IS NOT NULL
 ORDER BY name, id

最后,如果你想用每个名字显示整行,你可以这样做(http://sqlfiddle.com/#!2/eeec6/8/0):

SELECT name, n.id, n.a, n.b
  FROM (
        SELECT id, a AS name
          FROM names
         UNION 
        SELECT id, b AS name
          FROM names
        ) AS t
  JOIN names AS n ON t.id = n.id
 WHERE name IS NOT NULL
 ORDER BY name, n.id

答案 1 :(得分:0)

一种方法:

SELECT s.ColumnA AS digest_name
     , s.ID
     , s.ColumnA
     , s.ColumnB
  FROM mydata s
 WHERE s.ColumnA IS NOT NULL

 UNION ALL

SELECT t.ColumnB
     , t.ID
     , t.ColumnA
     , t.ColumnB
  FROM mydata t
 WHERE t.ColumnB IS NOT NULL

 ORDER BY 1, 3, 4

一个查询获取ColumnA不为null的所有行,第二个查询获取Column B不为null的行。 (这有效地省略了摘要名称为NULL的行。)

UNION ALL集合运算符将两组行合并为一组。 (注意:与UNION ALL运算符相比,我们更喜欢效率更高的UNION运算符,因为当不需要该运算时,它不会执行识别和删除重复行的额外工作。)

ORDER BY指定行首先按摘要名称排序,然后按ColumnAColumnB中的名称排序。


这会产生十行输出,并包含行:

digest   Id ColumnA  ColumnB
-------- -- -------- --------
Adam      4 NULL     Adam

不清楚为什么在问题中指定的结果集中省略了这一行。 (问题中的结果集只显示了九行。)

所以,我不确定我是否遗漏了有关要求的内容。我完全有可能不理解规范。