【问题标题】:Organizing data into multiple columns SQL将数据组织成多列 SQL
【发布时间】:2021-10-12 06:05:18
【问题描述】:

我有一个包含超过 500 万客户的表,其中包含历史活动数据,如下例所示:

Customer ID PART_ID Activity
12345 202012 2
12345 202101 0
12345 202102 5

我想将此数据转换为多列;行中的客户、列中的日期及其各自的活动信息。

我编写了下面的代码,但不是为单个客户创建单行,而是客户重复,我得到一个这样的表:

Customer ID 202012 202101 202102
12345 1 0 0
12345 0 0 0
12345 0 0 1

代替:

Customer ID 202012 202101 202102
12345 1 0 1

我做错了什么?

SELECT *
FROM
(
    SELECT CUST_ID, RULLED_PROFIT_CENTER,
      CASE WHEN PART_ID = 202012 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS ARA_20,
      CASE WHEN PART_ID = 202101 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS OCA_21,
      CASE WHEN PART_ID = 202102 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS SUB_21,
      CASE WHEN PART_ID = 202103 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS MAR_21,
      CASE WHEN PART_ID = 202104 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS NIS_21,
      CASE WHEN PART_ID = 202105 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS MAY_21,
      CASE WHEN PART_ID = 202106 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS HAZ_21,
      CASE WHEN PART_ID = 202107 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS TEM_21,
      CASE WHEN PART_ID = 202108 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS AGU_21,
      CASE WHEN PART_ID = 202109 AND ACTIVITY > 0 THEN 1 ELSE 0 END AS EYL_21
    FROM ACTIVITY
    WHERE RULLED_PROFIT_CENTER IN (108, 103, 170)
    GROUP BY CUST_ID, RULLED_PROFIT_CENTER
)
WHERE ARA_20 + OCA_21 + SUB_21 + MAR_21 + NIS_21 + MAY_21 +
      HAZ_21 + TEM_21 + AGU_21 + EYL_21 > 0

【问题讨论】:

  • 您按两件事进行分组,CUST_IDRULLED_PROFIT_CENTER,因此您将获得每个客户的多个列。 RULLED_PROFIT_CENTER 是什么?
  • RULLED_PROFIT_CENTER 是特定于客户的,客户只能有一个值。您也可以将其从查询中删除。
  • SUM / COUNT / MAX 聚合缺失。例如MAX (CASE WHEN PART_ID = 202012 AND ACTIVITY > 0 THEN 1 ELSE 0 END) AS ARA_20
  • 您使用的是哪种 DBMS 产品? “SQL”只是所有关系数据库都使用的一种查询语言,而不是特定数据库产品的名称。请为您使用的数据库产品添加tagWhy should I tag my DBMS
  • 感谢您的反馈。我正在使用 DBeaver DMBS,也作为标签添加。

标签: sql pivot dbeaver


【解决方案1】:
    WHERE RULLED_PROFIT_CENTER IN (108, 103, 170)
    GROUP BY CUST_ID, RULLED_PROFIT_CENTER

您按两个值进行分组,即客户和 RULLED_PROFIT_CENTER。 RULLED_PROFIT_CENTER 可以有三个可能的值,因此每个客户最多可以获得三行。如果您只希望每个客户一行,请从您的组中删除 RULLED_PROFIT_CENTER。

您可能将 RULLED_PROFIT_CENTER 添加到组 by,因为没有它,查询将无法工作。如果您想在您的选择中包含 RULLED_PROFIT_CENTER,但不是您的分组依据,您还需要聚合 RULLED_PROFIT_CENTER。即使每个客户只有一个价值。使用string_agg

SELECT CUST_ID, string_agg(RULLED_PROFIT_CENTER, ', ')

如果客户只有一个 RULLED_PROFIT_CENTER 值,您将只获得那个值。


由于您要将客户的所有行分组在一起,因此您需要获取活动的max

MAX( CASE WHEN PART_ID = 202012 AND ACTIVITY > 0 THEN 1 ELSE 0 END ) AS ARA_20

【讨论】:

  • 虽然 string_agg 不能作为函数工作,但在解决问题时将 max 添加到 case 中。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 1970-01-01
  • 2016-07-21
  • 1970-01-01
  • 2017-06-13
  • 2012-07-17
  • 1970-01-01
相关资源
最近更新 更多