[英]How to split / unpivot group_concat in mysql?
I currently have a view that has a column called alt_email_contact and I used the group_concat function in order to get multiple emails associated with one contact. 我目前在一个视图中有一列名为alt_email_contact的视图,并且使用group_concat函数来获取与一个联系人关联的多封电子邮件。 However I want to be able to extract each email and create a separate column for each. 但是,我希望能够提取每个电子邮件并为每个电子邮件创建一个单独的列。
Example: 例:
id email
1 SkyW@gmail.com, SW@gmail.com, WW@gmail.com, WalterW@gmail.com
the amount of emails is subject to change from one user to another therefore there wont always be four emails for each user. 电子邮件数量可能会从一个用户更改为另一个用户,因此每个用户不会总是有四个电子邮件。 I want to create a new column per each email like so: 我想为每封电子邮件创建一个新列,如下所示:
id email_1 email_2 email_3 email_4
1 SkyW@gmail.com SW@gmail.com WW@gmail.com WalterW@gmail.com
(I am using phpmyadmin) I would like to be able to modify my view to contain the variable amount of emails per user. (我正在使用phpmyadmin)我希望能够修改我的视图以包含每位用户可变数量的电子邮件。
You can use substring_index()
to achieve what you want. 您可以使用substring_index()
实现所需的功能。 It is not really pretty, but it will work: 它不是很漂亮,但是可以工作:
select id,
substring_index(emails, ', ', 1) as email_1
(case when length(emails) - length(replace(emails, ',', '')) >= 1
then substring_index(substring_index(emails, ', ', 2), ', ', -1)
end) as email_2,
(case when length(emails) - length(replace(emails, ',', '')) >= 2
then substring_index(substring_index(emails, ', ', 3), ', ', -1)
end) as email_3,
(case when length(emails) - length(replace(emails, ',', '')) >= 3
then substring_index(substring_index(emails, ', ', 4), ', ', -1)
end) as email_4,
(case when length(emails) - length(replace(emails, ',', '')) >= 4
then substring_index(substring_index(emails, ', ', 5), ', ', -1)
end) as email_5
from table t;
You can insert these values into another table, if you like. 如果愿意,可以将这些值插入另一个表中。
Don't use that view, since GROUP_CONCAT()
has already ruined the normalization. 不要使用该视图,因为GROUP_CONCAT()
已经破坏了规范化。 You want to simulate a pivot table using the limited SQL capabilities of MySQL. 您想使用MySQL的有限SQL功能来模拟数据透视表。
Let's assume that your view is based on a Contacts
table that looks like this: 假设您的视图基于如下所示的“ Contacts
表:
CREATE TABLE Contacts
( id INTEGER NOT NULL
, alt_email_contact VARCHAR(256) NOT NULL
);
Create this helper view instead (which is basically RANK() OVER (PARTITION BY id ORDER BY alt_email_contact)
, except that MySQL doesn't support RANK()
): 而是创建此帮助程序视图(基本上是RANK() OVER (PARTITION BY id ORDER BY alt_email_contact)
,除了MySQL不支持RANK()
):
CREATE VIEW NumberedContacts AS
SELECT c1.id, c1.alt_email_contact, COUNT(*) AS rank
FROM Contacts c1
INNER JOIN Contacts c2
ON c2.id = c1.id AND
c1.alt_email_contact >= c2.alt_email_contact
GROUP BY c1.id, c1.alt_email_contact;
Then you can write this query or view, which gives you up to 5 alternate e-mail addresses, ordered alphabetically: 然后,您可以编写此查询或视图,该查询或视图最多提供5个备用电子邮件地址,按字母顺序排列:
CREATE VIEW ContactsForImport AS
SELECT c1.id
, c1.alt_email_contact AS email_1
, c2.alt_email_contact AS email_2
, c3.alt_email_contact AS email_3
, c4.alt_email_contact AS email_4
, c5.alt_email_contact AS email_5
FROM NumberedContacts AS c1
LEFT OUTER JOIN NumberedContacts AS c2
ON c1.id = c2.id AND c2.rank = 2
LEFT OUTER JOIN NumberedContacts AS c3
ON c1.id = c3.id AND c3.rank = 3
LEFT OUTER JOIN NumberedContacts AS c4
ON c1.id = c4.id AND c4.rank = 4
LEFT OUTER JOIN NumberedContacts AS c5
ON c1.id = c5.id AND c5.rank = 5
WHERE c1.rank = 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.