我有一张看起来像这样的桌子:
| 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 查询在开始读取数据之前,其选择列表中必须有一组固定的列。您无法创建基于其读取的数据扩展自身的 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