将单元格值转换为 MySQL 中的列

问题描述 投票:0回答:1

我有一张看起来像这样的桌子:

|  EMAIL  |  LIST   |   STATUS     | ISP_GROUP   |  SENT_DATE   |  CREATED_DATE   |
----------------------------------------------------------------------------------
| email1  |  list1  |   active     |    GMAIL    |  2024-06-01  |  2024-05-30     |
| email1  |  list2  |  complain    |    GMAIL    |  2024-06-12  |  2024-05-10     |
| email2  |  list1  |  unsubscribe |    YAHOO    |  2024-05-25  |  2024-05-01     |
| email2  |  list2  |   active     |    YAHOO    |  2024-06-15  |  2024-05-15     |
| email2  |  list3  |   active     |    YAHOO    |  2024-06-20  |  2024-06-11     |

一封电子邮件可以位于多个列表中,并且每个列表具有不同的状态。

电子邮件只能位于 ISP_GROUP 上。 在上面的示例中,email1 是 GMAIL 帐户。 email1 可能位于 12 个列表中,但始终是 GMAIL 帐户。

我需要将每个列表放入其自己的列中,然后在后续列中列出每个列表的状态,并且还在其自己的列中包含 SENT_DATE 和 CREATED_DATE。

这是我想要实现的目标的示例:

| EMAIL  | ISP_GROUP | LIST1_STATUS | LIST1_SENT_DATE | LIST1_CREATED_DATE | LIST2_STATUS | LIST2_SENT_DATE | LIST2_CREATED_DATE | and so on.. |
------------------------------------------------------------------------------------------------------------------------------------------------
| email1 | GMAIL     |    active    |    2024-06-01   |      2024-05-30    |   complain   |    2024-06-12   |     2024-05-10     | 
| email2 | YAHOO     |  unsubscribe |    2024-05-25   |      2024-05-01    |   active     |    2024-06-15   |     2024-05-15     | 

所以类似的事情。

总共有 15 个列表,那么结果将是一个非常长的数据集。

如果电子邮件不在特定列表中,则它可以为 NULL。

我写了一个这样的查询:

SELECT 
`email` 
,`isp_group`
, GROUP_CONCAT(`Lists`) AS 'Lists'
FROM `list_main` 
GROUP BY `email`, `isp_group`
ORDER BY `email` DESC

返回这样的结果:

|   EMAIL  |   ISP_GROUP  |         LISTS          |
----------------------------------------------------
|   email1 |   GMAIL      |  list1, list2          |
|   email2 |   YAHOO      |  list1, list2, list3   |

但我想让每个列表都有自己的列以及日期。 我不知道该怎么做。

这能实现吗? 如果是这样,请帮忙。

谢谢你。

sql mysql mysql-5.7
1个回答
0
投票

具有可变列数的数据透视查询始终需要两次传递。您需要知道有多少列,因为 SQL 查询在开始读取数据之前,其选择列表中必须有一组固定的列。您无法创建基于其读取的数据扩展自身的 SQL 查询。

这是生成您描述的数据透视表的查询示例:

SELECT
  email,
  MAX(isp_group),

  -- columns for list1
  MAX(CASE list WHEN 'list1' THEN status END) AS LIST1_STATUS,
  MAX(CASE list WHEN 'list1' THEN sent_date END) AS LIST1_SENT_DATE,
  MAX(CASE list WHEN 'list1' THEN created_date END) AS LIST1_CREATED_DATE,

  -- columns for list2
  MAX(CASE list WHEN 'list2' THEN status END) AS LIST2_STATUS,
  MAX(CASE list WHEN 'list2' THEN sent_date END) AS LIST2_SENT_DATE,
  MAX(CASE list WHEN 'list2' THEN created_date END) AS LIST2_CREATED_DATE

  -- repeat the set of three columns for each list, up to the max number of lists

FROM list_main
GROUP BY email;

给定样本数据的输出:

+--------+----------------+--------------+-----------------+--------------------+--------------+-----------------+--------------------+
| email  | MAX(isp_group) | LIST1_STATUS | LIST1_SENT_DATE | LIST1_CREATED_DATE | LIST2_STATUS | LIST2_SENT_DATE | LIST2_CREATED_DATE |
+--------+----------------+--------------+-----------------+--------------------+--------------+-----------------+--------------------+
| email1 | GMAIL          | active       | 2024-06-01      | 2024-05-30         | complain     | 2024-06-12      | 2024-05-10         |
| email2 | YAHOO          | unsubscribe  | 2024-05-25      | 2024-05-01         | active       | 2024-06-15      | 2024-05-15         |
+--------+----------------+--------------+-----------------+--------------------+--------------+-----------------+--------------------+

Dbfiddle,使用 MySQL 5.7 进行测试:https://www.db-fiddle.com/f/gjxHuzM7hKeyidVu8Q7GGj/0

© www.soinside.com 2019 - 2024. All rights reserved.