简单的SQL查询,用于展平行中的多个属性

时间:2016-11-30 18:18:04

标签: sql postgresql case pgadmin flatten

我首先尝试在Excel中解决我的问题而没有简单的修复,所以决定用SQL(在PostgreSQL / pgAdminIII上),我是初学者,在那里我找不到令人满意的解决方案。

我的目标是在一行中“展平”包含类似属性的数据集,该行应该有一行。

一个例子可能会澄清。我的数据列出了购物袋及其内容如下:

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返回所有匹配,而不仅仅是第一个匹配,那将是非常好的。我目前的解决方法是使用一系列 CASE UNION ALL (参见下面的苹果和香蕉示例),但不切实际,因为我的完整数据包含了大约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 个答案:

答案 0 :(得分: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

答案 1 :(得分:-1)

我使用sql进行报告,但是找不到我的代码。 但这是我发现快速搜索的内容。 Convert Rows to columns using 'Pivot' in SQL Server