2012-02-08 76 views
2

我有一個表,它採用以下形式:取消壓扁表

person, date, food1, food2, food3 

我想借這個表,並得到一個結果,看起來像這樣:

person, date, foodId 

所以對於例如,如果我在原來的表有一行是這樣的:

Andy, 1/1/2012,false,true,true 

我會得到一個結果,看起來像這樣

Andy, 1/1/2012, food2 
Andy, 1/1/2012, food3 

到目前爲止,我有

SELECT person, date, 
(
    case 
     when food1 = true then 'food1' 
     when food2 = true then 'food2' 
     when food3 = true then 'food3' 
    end 
) as foodId 

但這只是抓住每源行一個結果時,有可能高達每源行3個結果。任何方式,我可以修復我的查詢,從我的例子,而不是隻有一個獲得2行?

回答

0

試試這個:

(SELECT person, date, 'food1' as foodId from table where food1 = true 
UNION ALL 
SELECT person, date, 'food2' as foodId from table where food2 = true 
UNION ALL 
SELECT person, date, 'food3' as foodId from table where food3 = true 
) ORDER BY person 

編輯(在響應評論)

如果您需要將其放入臨時表中,將查詢更改爲:

select person, date, FoodId 
into #my_temp_table 
from (
    SELECT person, date, 'food1' as foodId from table where food1 = true 
    UNION ALL 
    SELECT person, date, 'food2' as foodId from table where food2 = true 
    UNION ALL 
    SELECT person, date, 'food3' as foodId from table where food3 = true 
) table_alias 
+0

我怎樣才能把它放到臨時表中? – sooprise 2012-02-08 21:04:42

+0

@sooprise我給答案增加了一個例子。 – dasblinkenlight 2012-02-08 21:11:17

0

我知道做到這一點的唯一方法是使用三個查詢:

INSERT INTO Table2 (person, date, foodID) SELECT person, date, 'food1' FROM Table1 WHERE food1; 
INSERT INTO Table2 (person, date, foodID) SELECT person, date, 'food2' FROM Table1 WHERE food2; 
INSERT INTO Table2 (person, date, foodID) SELECT person, date, 'food3' FROM Table1 WHERE food3; 
+0

哎,這是一種醜陋的。希望有更好的方法,但我會開始編碼,以防萬一。謝謝:) – sooprise 2012-02-08 20:34:43

+0

看起來像兩個其他人給出了相同的答案,我會繼續前進,並做到這一點。謝謝! – sooprise 2012-02-08 20:39:53

0

嘗試

SELECT person, date, 'food1' AS foodID FROM YourTable1 WHERE food1 = true 
UNION ALL 
SELECT person, date, 'food2' AS foodID FROM YourTable1 WHERE food2 = true 
UNION ALL 
SELECT person, date, 'food3' AS foodID FROM YourTable1 WHERE food3 = true 
2

可以unpivot的數據:Using PIVOT and UNPIVOT

設置:

create table diet(person varchar(10), entry datetime, food1 varchar(10), food2 varchar(10), food3 varchar(10)) 
insert into diet values('John', CURRENT_TIMESTAMP, 'Apple','Pizza','Cake'); 

逆透視查詢:

SELECT person, entry, meal, food 
FROM 
    (SELECT person, entry, food1, food2, food3 
    FROM diet) p 
UNPIVOT 
    (food FOR meal IN 
     (food1, food2, food3) 
    )AS unpvt; 

輸出:

person entry meal food 
John 2012-02-08 14:42:22.940 food1 Apple 
John 2012-02-08 14:42:22.940 food2 Pizza 
John 2012-02-08 14:42:22.940 food3 Cake 
0

爲什麼要在SQL中這樣做?演示應該在表示層而不是數據操作層完成。

除了架構「醜陋」之外,還會產生一些性能損失:將查詢結果返回給客戶端時,您的DBMS現在不得不傳輸最多3個簡單的布爾值行,重複persondate,加上food表示爲字符串而不是布爾值。


OTOH,如果你真的想重新設計你的數據模型,並需要一種方法來從舊模式到新的傳輸數據,以及那是另一回事......