不展平桌子

时间:2012-02-08 20:30:00

标签: sql

我有一个表格,其格式如下:

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行而不只是一行吗?

5 个答案:

答案 0 :(得分:2)

您可以解决数据: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');

Unpivot查询:

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

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

答案 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

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

答案 4 :(得分:0)

为什么要在SQL中执行此操作?演示文稿应该在表示层中完成,而不是数据操作层。

除了架构“丑陋”之外,您还会产生一些性能损失:将查询结果返回给客户端时,而不是使用简单的布尔值传输一行,您的DBMS现在必须最多传输3行,重复persondate,加上food表示为字符串而不是布尔值。


OTOH,如果您真的想重新设计数据模型并需要一种方法将数据从旧模型传输到新模型,那么这是另一回事......