【问题标题】:Mysql - Merge multiple columns into one while preserving each valueMysql - 将多列合并为一列,同时保留每个值
【发布时间】:2015-04-26 21:41:55
【问题描述】:

Mysql 中是否有一种简单的方法可以将多列结果集转换为单列结果集,其中单列中的每一行都包含来自多列结果集中每个单元格的单个值?

例如,假设我有一张这样的表:

    id    |   fk1   |   fk2   |   fk3   
    1          2         3         4
    5          6         7         8

理想情况下,我希望能够按照以下方式运行查询:

SELECT <some_function>(fk1, fk2, fk3) AS value FROM myTable;

...然后得到如下输出:

  value  
    2
    3
    4
    6
    7
    8

是否有一种直接的方法,或者是在代码中遍历多列结果集并将值提取为我想要的格式的唯一真正选择?

最终目标是能够在输入只能是单列值的上下文中将第一个查询用作子查询,例如:

SELECT * FROM myOtherTable WHERE id IN 
    (SELECT <some_function>(fk1, fk2, fk3) AS value FROM myTable);

因此,如果存在纯 SQL 解决方案,则更可取。

【问题讨论】:

    标签: mysql sql merge multiple-columns


    【解决方案1】:

    最简单的方法是使用union all

    select fk1 from mytable union all
    select fk2 from mytable union all
    select fk3 from mytable;
    

    还有其他方法,但这是最简单的。

    对于您的特定查询,您可以使用existsorin

    SELECT mo.*
    FROM myOtherTable mo
    WHERE EXISTS (SELECT 1
                  FROM MyTable m
                  WHERE mo.id IN (m.fk1, m.fk2, m.fk3)
                 );
    

    编辑:

    为了性能,但在每个fk 列上都有一个索引并在where 中使用多个条件:

    SELECT mo.*
    FROM myOtherTable mo
    WHERE EXISTS (SELECT 1 FROM MyTable m WHERE mo.id = m.fk1) OR
          EXISTS (SELECT 1 FROM MyTable m WHERE mo.id = m.fk2) OR
          EXISTS (SELECT 1 FROM MyTable m WHERE mo.id = m.fk3);
    

    这将进行索引查找,这应该比原始表单快得多。

    【讨论】:

    • 谢谢,where exists 方法有效(没有尝试过union all,因为myTable 上的查询实际上有自己的子查询,我不想为每个字段重复一次) ,但比仅查询和迭代多列结果集花费的时间要长得多。有什么想法可以加快速度吗?
    • @aroth 。 . .加快速度是完全不同的事情。为此,我建议对数据结构进行规范化,以便每行只有一个 fk
    • 我害怕那个。不幸的是,在许多不同的地方都有相当多的遗留代码是围绕单独的字段构建的。如果我只选择多个列,查询会非常快,所以我想我会这样做并以编程方式处理其余部分。
    【解决方案2】:

    考虑一下你的表名 tab1。

    现在你可以像这样查询了

    select fk1 from (
       (select fk1 from tab1) 
          union all 
       (select fk2 from tab1)) as rt 
          group by fk1;
    

    这会将您的两列合并为一列。包含将一个接一个出现。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-25
      • 2021-03-11
      • 1970-01-01
      • 2022-11-19
      相关资源
      最近更新 更多