2013-07-20 29 views
-1

对于表如下所示如何将行值分组为列?

Animal  LiveIn 
------  ------ 

Cat   land 
fish   water 
frog   land 
frog   water 
salamander land 
salamander water 

我需要的结果如下

Animal  Column1 Column2 
------  ------- ------- 
cat   land  *null* 
fish   water  *null* 
frog   land  water 
salamander land  water 

回答

2

我建议你这个使用row_number()和有条件的聚集做:

select t.animal, 
     max(case when seqnum = 1 then livein end) as Column1, 
     max(case when seqnum = 2 then livein end) as Column2 
from (select t.*, row_number() over (partition by animal order by (select NULL)) as seqnum 
     from t 
    ) t 
group by t.animal; 

请注意,您没有办法表达数据中列的排序--SQL表本质上是无序的。以上选择任意排序。如果您有idCreatedAt列,则可以使用它来指定顺序。

由于没有订货,下面也做了相当的工作:

select t.animal, min(t.LiveIn) as Column1, 
     (case when min(t.LiveIn) <> max(t.LiveIn) then max(t.LiveIn) end) as Column2 
from t 
group by t.animal; 

编辑:

SQL查询必须返回列的固定数量。你不能有一个查询有时返回三列,有时四个。你可以,但是,调整的查询返回较大的列数,通常可能是NULL

select t.animal, count(*) as NumLiveIn, 
     max(case when seqnum = 1 then livein end) as Column1, 
     max(case when seqnum = 2 then livein end) as Column2, 
     max(case when seqnum = 3 then livein end) as Column3, 
     max(case when seqnum = 4 then livein end) as Column4 
from (select t.*, row_number() over (partition by animal order by (select NULL)) as seqnum 
     from t 
    ) t 
group by t.animal; 

在这种情况下,我也对环境的数量增加一列,以及。

+0

我不知道有多少列会有。例如,如果有另一个数据需要一只鸟,它居住在海,水和天空中。我怎样才能做到这一点。这真的不可能吗?如果出现这样的要求,我应该怎么做? –

+0

我不会为命令而烦恼,它对我来说真的不重要!谢谢 –

+0

请大胆**这个SQL查询必须返回固定数量的列。你不能有一个查询有时返回三列,有时四个** –

1

你的代码很混乱;什么是'-----'应该显示我?

你有重复的价值观和你想对它们进行“分组”的权利。 看看规范化,因为您好像涉及数据库的模式级别并要求提供DDL codehttps://en.wikipedia.org/wiki/Database_normalization

如果前两个'------'实际上是两个表,我会建议对该模式进行以下返工。

Animal Environment Animal_Environment 
------ ------   ------ 
id  id    animal_id 
name  name   environment_id 

因此,我们避免在我们的数据库中重复内容。 也导致该内容更简单DML queries

+0

----没有什么,但将列名与值分开。我认为这张桌子有一个标准化的结构。但我的要求可能有点奇怪 –

+0

他们不是两张桌子。他们是两列。谢谢 –

+0

@ t-clausen我这样做,去钓鱼。 – wurde

1

这不正是你问什么,但它是解决它的另一种方式:

declare @t table(Animal varchar(10), LiveIn varchar(7)) 
insert @t values 
('Cat','land'),('fish','water'),('frog','land'), 
('frog','water'),('salamander','land'),('salamander','water') 

select * from @t 
PIVOT 
(min([LiveIn]) 
FOR Livein 
in([land],[water]) 
)AS p ORDER BY 1 

结果:

Animal  land Water 
______________________ 
Cat  land NULL 
fish  NULL water 
frog  land water 
salamander land water 
+0

说这张表不是标准化的。请参阅@wurde的答案。有人高举他。我不知道我做了什么错误。我相信桌子是正常化的。有时我的要求可能会很奇怪。 –