2013-07-20 60 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的答案。有人高舉他。我不知道我做了什麼錯誤。我相信桌子是正常化的。有時我的要求可能會很奇怪。 –