MySQL GROUP_CONCAT和DISTINCT

时间:2013-10-08 09:54:27

标签: mysql sql

我有这样的tb1表:

name   email               link
john   myemail@gmail.com   google
john   myemail@gmail.com   facebook
john   myemail2@gmail.com  twitter
....
....
and more

当我使用查询调用数据时

SELECT name, email, group_concat(DISTINCT link SEPARATOR '/') as source
FROM tb1
group by email

结果像这样:

NAME    EMAIL               SOURCE
john    myemail2@gmail.com  twitter
john    myemail@gmail.com   facebook/google
....
....
and more

sqlfiddle

我想让结果看起来像:

NAME    EMAIL               SOURCE 1       SOURCE 2
john    myemail2@gmail.com  twitter
john    myemail@gmail.com   facebook       google

只能通过查询来生成结果吗?

注意:我想制作动态列源1,2,3 ......,n

3 个答案:

答案 0 :(得分:2)

我的回答是,不要这样做!

您想要做的是称为旋转。在MySQL中,这通常是用一个地狱的

来完成的
....
aggregate_function(case when ...),
aggregate_function(case when ...),
aggregate_function(case when ...),
...

块。但是由于您不了解所有源代码,因此您必须编写一个过程来为您动态构建语句并执行它。即便如此,你最终会得到像

这样的表结构
NAME    EMAIL               twitter     facebook    google
----------------------------------------------------------
john    myemail2@gmail.com  yes         no          no
john    myemail@gmail.com   no          yes         yes

那么,您的应用程序的程序员将如何知道列的命名方式?

为避免这种情况,您必须再次执行存储过程中的一个程序设计,以将每封电子邮件的行值放入一列。那么你将如何确定哪一行进入哪一列?如果facebook出现在列source1中的一行和列source2中的另一行中,该怎么办?在您的应用程序中,您必须测试或以其他方式确定实际有多少列,或者每个用户/电子邮件只能有2个来源?

总结一下,像这样的结果

name   email               link
john   myemail@gmail.com   google
john   myemail@gmail.com   facebook
john   myemail2@gmail.com  twitter

非常好,应由程序开发人员来处理它。对于他们来说,这比对团队中的数据库人员要容易得多。

答案 1 :(得分:1)

不,你不能因为使用MySQL而无法动态创建额外的列...(这更像是一个olap的东西或者允许这样的功能,称为数据透视表)

答案 2 :(得分:1)

它适用于这种情况,但它不是动态查询,只有当同一个电子邮件最多有2个链接时才能工作。

SELECT `name`, email, 
substring_index(group_concat(DISTINCT link SEPARATOR '/'),'/',1) as source_1,
if(group_concat(DISTINCT link SEPARATOR '/') like '%/%',
substring_index(group_concat(DISTINCT link SEPARATOR '/'),'/',-1),'') as source_2
FROM test2 group by email

如果您知道每封电子邮件中链接的确切可能性,则可以相应地修改相同的查询。