2016-11-30 38 views
1

我第一次嘗試在Excel中解決我的問題並沒有簡單的修復,所以決定在SQL(PostgreSQL/pgAdminIII)中給它一個鏡頭,我是初學者,我沒有找到令人滿意的解決方案。簡單的SQL查詢來扁平化一個行中的多個屬性

我的目標是「扁平化」一行中包含相似屬性的數據集,它們應該有自己的一行。

舉例說明。我的數據列出購物袋,其內容如下:

id material color fruit1 fruit2 fruit3 
1 cotton red apple banana cherry 
2 paper blue apple cherry 
3 plastic red banana 

我需要創建一個表格,表格中每個水果一個新行,所以查詢的結果應該是這樣的:

id material color fruit 
1 cotton red apple 
1 cotton red banana 
1 cotton red cherry 
2 paper blue apple 
2 paper blue cherry 
3 plastic red banana 

到目前爲止,我想出了一個涉及CASE的查詢,但這隻返回第一個匹配項,所以不會返回所有需要的行。

SELECT 
    id, 
    (CASE 
     WHEN 'apple' IN(fruit1, fruit2, fruit3) THEN 'apple_exh'   
     WHEN 'banana' IN(fruit1, fruit2, fruit3) THEN 'banana_exh' 
     WHEN 'cherry' IN(fruit1, fruit2, fruit3) THEN 'cherry_exh'    
     ELSE 'Error' 
    END) as "Fruit_Here" 
FROM 
    mydb.shopping 
WHERE 
'apple' IN(fruit1, fruit2, fruit3) 
OR 
'banana' IN(fruit1, fruit2, fruit3) 
OR 
'cherry' IN(fruit1, fruit2, fruit3) 

ORDER BY id; 

返回

id; fruit_here 
1;"apple_exh" 
2;"apple_exh" 
3;"banana_exh" 

這將是非常好的,如果一招存在允許情況下返回所有匹配,而不僅僅是第一。我目前的解決方法是使用CASE聯合全部(參見下面的蘋果和香蕉示例)作品,但這是不現實的乏味,因爲我的完整數據包括大約30個水果(可能我應該應用相同的「展平」蔬菜,最初也在一排)。

SELECT 
    id, 
    (CASE 
     WHEN 'apple' IN(fruit1, fruit2, fruit3) THEN 'apple_exh'       
     ELSE 'Error' 
    END) as "Fruit_Here" 
FROM 
    mydb.shopping 
WHERE 
'apple' IN(fruit1, fruit2, fruit3) 

UNION ALL 

SELECT 
    id, 
    (CASE 
     WHEN 'banana' IN(fruit1, fruit2, fruit3) THEN 'banana_exh' 
     ELSE 'Error' 
    END) as "Fruit_Here" 
FROM 
    mydb.shopping 
WHERE 
'banana' IN(fruit1, fruit2, fruit3) 

UNION ALL 

SELECT 
    id, 
    (CASE 
     WHEN 'cherry' IN(fruit1, fruit2, fruit3) THEN 'cherry_exh' 
     ELSE 'Error' 
    END) as "Fruit_Here" 
FROM 
    mydb.shopping 
WHERE 
'cherry' IN(fruit1, fruit2, fruit3) 

ORDER BY id, "Fruit_Here"; 

返回

id; fruit_here 
1;"apple_exh" 
1;"banana_exh" 
1;"cherry_exh" 
2;"apple_exh" 
2;"cherry_exh" 
3;"banana_exh" 

我的問題:是否有執行SQL這項任務,而不必重複代碼爲每種類型的水果,其他任何明顯的方法?

回答

2

你只需要一個select語句爲每列:

select id, material, color, fruit1 from mydb.shopping where fruit1 is not null 
union 
select id, material, color, fruit2 from mydb.shopping where fruit2 is not null 
union 
select id, material, color, fruit3 from mydb.shopping where fruit3 is not null 
+0

非常感謝您閱讀我的問題並發表本文!這確實是我尋找的簡單解決方案。知道單獨的選擇語句實際上排列在同一列中的位置在語句中的位置,而不管源列的名稱如何,這非常有幫助。因此,所有的果實都在一個標有「fruit1」的列中對齊,這正是我所需要的。 – sc28