将mysql中的列分成多列

Divide the columns in mysql into multiple columns

我对 mysql 完全陌生。在这里,我试图在 mysql 中进行查询,该查询根据其类别 (col2) 将列 col1 分为 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';

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

给定 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

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

Edit: I guess the question is not clear about the format of final answer. Thanks @philipxy for pointing out. Final answer should be adjusted in least number of rows (which is 2 in my case). All the columns should have equal number of rows and if some column has lesser values then that row will have NULL value in respective columns e.g col2 and col 4 above. Finally all the columns should be in sorted order where NULL will be in the last(if any)e.g Suppose there was an entry named Olly with category fourth then it should appear before NULL in col4 and after Ashley.

这很棘手。您正在尝试垂直而不是水平地堆叠列表,这不是 "normal" 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;