MySQL是否有用于“CONTAINS”的聚合函数?

8

假设我有以下数据集:

  用户  | 组
--------+-------
a@a.com |   A
a@a.com |   B
b@b.com |   A
c@c.com |   B
d@d.com |   A
d@d.com |   B
d@d.com |   C

我想将其转换为以下表格:

  用户  | IN_A  | IN_B  | IN_C
--------+-------+-------+-------
a@a.com | TRUE  | TRUE  | FALSE
b@b.com | TRUE  | FALSE | FALSE
c@c.com | FALSE | TRUE  | FALSE
d@d.com | TRUE  | TRUE  | TRUE

我已经得到了以下查询语句:

SELECT
  user,
  IF(LOCATE('A', GROUP_CONCAT(group)) > 0, TRUE, FALSE) AS IN_A,
  IF(LOCATE('B', GROUP_CONCAT(group)) > 0, TRUE, FALSE) AS IN_B,
  IF(LOCATE('C', GROUP_CONCAT(group)) > 0, TRUE, FALSE) AS IN_C
FROM users
GROUP BY user

我想知道是否有更好的方法来判断一个聚合字段是否包含一个值,或者这是唯一的方法吗?

5个回答

20

正确的做法:

SELECT
   user,
   IF(SUM(group = 'A'), TRUE, FALSE) AS IN_A,
   IF(SUM(group = 'B'), TRUE, FALSE) AS IN_B,
   IF(SUM(group = 'C'), TRUE, FALSE) AS IN_C
FROM users
GROUP BY user

运行得非常完美! - Daniel Beardsley

1
您可以尝试类似这样的代码片段:
SELECT distinct user,  
IF(EXISTS
    (SELECT users_a.user 
        from users as users_a 
    where users_a.group = 'A' and
        users_a.user = users.user), 
TRUE, FALSE) as IN_A,
IF(EXISTS
    (SELECT users_b.user 
        from users as users_b 
    where users_b.group = 'B' and
        users_b.user = users.user), 
TRUE, FALSE) as IN_B,
IF(EXISTS
    (SELECT users_c.user 
        from users as users_c 
    where users_c.group = 'C' and
        users_c.user = users.user), 
TRUE, FALSE) as IN_C
FROM `users` WHERE 1

尝试了这里,运行良好!


1

我想这是唯一的方法,即GROUP_CONCAT


我找到的另一种方法是 SELECT u.user, u1.group, g2.group FROM users u LEFT JOIN users u1 ON u.user = u1.user AND u1.group = "A" LEFT JOIN users u2 ON u.user = u2.user AND u2.group = "B" GROUP BY u.user; - Nick

0

不确定你会有多少组,但如果数量是有限的,我建议为每个组创建一列或使用 mysql 数据类型 SET(位掩码)。


它是有限的 - 我正在尝试从双键(用户/组)系统转移到单键(用户)系统,每个组都有自己的列。 - Nick

0

我不确定这是否是您的做法(因为我在这里还很新),但如果那是您使用的示例,那么使用用户、IN_A、IN_B和IN_C列会更容易。特别是因为这样您就不必再次重复用户数据。


这正是我想要实现的目标 :) 数据集使用用户和组作为双列主键。我想将用户作为主键,并将组拆分为列。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接