将mysql中的列分成多列

Posted

技术标签:

【中文标题】将mysql中的列分成多列【英文标题】:Divide the columns in mysql into multiple columns 【发布时间】:2017-06-22 13:31:23 【问题描述】:

我对 mysql 完全陌生。在这里,我尝试在mysql 中进行查询,它将col1 列根据其类别(col2)按如下所示的排序顺序分为4 个不同的列。到目前为止,我已经写了一个这样的查询:

select if(category = 'first',name ,NULL) as first,
if(category = 'second',name,NULL) as second,
if(category = 'third',name,NULL) as third,
if(category = 'fourth',name,NULL) as fourth
from 'table';

这段代码给了我四列,但我现在卡住了,因为我无法进一步过滤它。

给定表:

name     category
John     first
Sunil    third
Jenny    third
Ashley   fourth
Meera    second
Abhay    first

必答:

col1    col2    col3    col4
Abhay   Meera   Jenny   Ashley
John    NULL    Sunil   NULL

请注意,答案中的所有列都已排序。

编辑:我想这个问题并不清楚最终答案的格式。感谢@philipxy 指出。最终答案应至少调整行数(在我的情况下为 2)。所有列的行数应该相等,如果某些列的值较小,则该行将在各自的列中具有NULL 值,例如上面的col2col 4。最后,所有列都应该按排序顺序排列,其中NULL 将在最后一个(如果有的话)例如假设有一个名为Ollycategory fourth 的条目,那么它应该出现在NULL 之前@987654335 @ 和 Ashley 之后。

【问题讨论】:

是否需要输出假设只有 2 行?还是可能有更多取决于原始表中的行数? 可以有更多行。我在这里仅展示了一个示例。 你为什么要这样做?这将值强制到表的行中,就好像它是一个 gui 网格一样。您可能不应该在 sql 表中进行格式化,而应该在 gui 中进行格式化。考虑到您不知道“select t.*”是什么意思。你几乎肯定不想要你想要的结果。 【参考方案1】:

这很棘手。您正在尝试垂直堆叠列表,而不是水平堆叠列表,这不是“正常”的 SQL 操作。

您可以使用条件聚合来做您想做的事。问题是没有什么可以聚合的。解决方法是引入一个可变列来计算一个序列号进行聚合:

select max(case when category = 'first' then name end) as first,
       max(case when category = 'second' then name end) as second,
       max(case when category = 'third' then name end) as third,
       max(case when category = 'fourth' then name end) as fourth
from (select t.*,
             (@rn := if(@c = category, @rn + 1,
                        if(@c := category, 1, 1)
                       )
             ) as rn
      from `table` t cross join
           (select @c := '', @rn := 0) params
      order by category
     ) t
group by rn;

如果您希望每列中的值按特定顺序排列,请在 category 之后添加第二个排序键。

编辑:

我应该注意,如果您不需要多行,而只需要值,则可以将它们连接在一起:

select group_concat(case when category = 'first' then name end) as firsts,
       group_concat(case when category = 'second' then name end) as seconds,
       group_concat(case when category = 'third' then name end) as thirds,
       group_concat(case when category = 'fourth' then name end) as fourths
from`table` t
group by rn;

【讨论】:

你能解释一下你的代码中使用变量的逻辑吗?我也不明白这部分:select t.*t.*是什么? @SunilKumar 。 . t 是表别名。您可以在文档 (dev.mysql.com/doc/refman/5.7/en/user-variables.html) 中了解用户定义的变量。如果您想查看子查询如何用于此查询,请自行运行子查询。 请参考 MySQL(或 any SQL DBMS)规范,该规范将 SELECT 中的变量赋值与 FROM 定义为对每一行执行变量赋值,在ORDER BY order,在包含表达式之前使用子选择?您声称此答案是该问题的解决方案依赖于它,但尽管链接文档中有一些隐晦的暗示性短语,但此语义并未在任何地方记录。 @philipxy 。 . .子查询定义rn

以上是关于将mysql中的列分成多列的主要内容,如果未能解决你的问题,请参考以下文章

如何将多列中的数据分离并解析成单独的行(Oracle)

将列表的列拆分为同一 PySpark 数据框中的多列

PySpark 将“map”类型的列转换为数据框中的多列

如何使用VBA隐藏多列列表框中的列

SQL 怎么将一列中的数据按一个分隔符分成多列显示

将多个字符串拆分为多列