如下表所示
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
答案 0 :(得分: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表本质上是无序的。以上选择任意顺序。如果您有id
或CreatedAt
列,则可以使用该列指定订单。
鉴于没有订购,以下也做了同等的工作:
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;
在这种情况下,我还会为环境数添加一列。
答案 1 :(得分:1)
你的代码令人困惑;什么是'-----'应该向我展示?
您有重复的值以及想要“分组”它们的权利。 看看规范化,因为您似乎参与了数据库的模式级别并要求DDL code。 https://en.wikipedia.org/wiki/Database_normalization
如果前两个'------'实际上是两个表,我建议对该模式进行以下修改。
Animal Environment Animal_Environment
------ ------ ------
id id animal_id
name name environment_id
有了这个,我们避免重复数据库中的内容。 对于该内容,也会导致更简单的DML queries。
答案 2 :(得分: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