SQL中的数据转换

时间:2019-04-16 16:00:27

标签: sql

我在这里是新手,所以如果您以前曾问过这个问题,或者我没有尽我所能,请原谅我。

我正在尝试以所需的格式转换下面的数据表,但是到目前为止我还没有遇到太多的运气。所有想法都将不胜感激。

我的表当前如下所示:

Name       attribute_1      attribute_2       attribute_3

John         5543              4523              2554
Paul         4523              5543              9523
Anna         2554              5543              2554

其中的单元格是策略代码。

我正在尝试将其转换为:

 strategy_id   attribute_1      attribute_2       attribute_3
    5543            1                2                 0
    2554            1                0                 2
    4523            1                1                 0
    9523            0                0                 1

其中的单元格是策略ID确定特定属性的次数的计数。

我尝试了以下代码:

    SELECT t.strategy_id,
       SUM(t.attribute_1) AS attribute_1,
       SUM(t.attribute_2) AS attribute_2,
       SUM(t.attribute_3) AS attribute_3
 FROM (
        SELECT s.strategy_id,
               CASE WHEN s.strategy_id = a.attribute_1 THEN 1 ELSE 0 END AS attribute_1,
               CASE WHEN s.strategy_id = a.attribute_2 THEN 1 ELSE 0 END AS attribute_2,
               CASE WHEN s.strategy_id = a.attribute_3 THEN 1 ELSE 0 END AS attribute_3
          FROM strategies s
    CROSS JOIN attributes a) t
    GROUP BY t.strategy_id

基本上,我创建了另一个名为 strategies 的表,该表只是一个包含 strategy id 的列。然后,我交叉联接 attributes 表,以得到一个表,该表的每个名称和策略ID包含一个策略应用于每个属性的次数。最后,我按strategy_id分组以获得所需的表。

我的解决方案有效,但是我对背后逻辑的“简洁性”感到不满意。我也担心性能,因为这将需要在大数据量上运行。

我真的希望这有道理。

谢谢, 阿黛拉

2 个答案:

答案 0 :(得分:0)

我认为取消数据透视然后重新聚合可能会更简单。可能看起来像:

select strategy,
       sum(attribute_1) as attribute_1,
       sum(attribute_1) as attribute_2,
       sum(attribute_3) as attribute_3
from ((select attribute_1 as strategy, 1 as attribute_1, 0 as attribute_2, 0 as attribute_3
       from attributes
      ) union all
      (select attribute_2 as strategy, 0 as attribute_1, 1 as attribute_2, 0 as attribute_3
       from attributes
      ) union all
      (select attribute_3 as strategy, 0 as attribute_1, 0 as attribute_2, 1 as attribute_3
       from attributes
      )
     ) a
group by strategy;

如果您的数据库支持横向连接,则可以大大简化。

答案 1 :(得分:0)

这是使用联合的替代解决方案:

SELECT
    attribute AS strategy_id,
    COUNT(CASE WHEN col = 1 THEN 1 END) AS attribute_1,
    COUNT(CASE WHEN col = 2 THEN 1 END) AS attribute_2,
    COUNT(CASE WHEN col = 3 THEN 1 END) AS attribute_3
FROM
(
    SELECT attribute_1 AS attribute, 1 AS col FROM attributes
    UNION ALL
    SELECT attribute_2, 2 FROM attributes
    UNION ALL
    SELECT attribute_3, 3 FROM attributes
) t
GROUP BY
    attribute;

enter image description here

Demo

此处的策略是首先通过两个联合将所有strategy_id值放入一个列中。然后,通过strategy_id进行汇总,然后为三个属性列中的每一个取整。