问题
Say I have this data set
user | group --------+------- 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
I want to convert this into a table like this:
user | 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
I've got:
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
What I'm wondering is if there is a better way to known if an aggregated field contains a value, or if this is the only way?
回答1:
The right way to do it:
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
回答2:
I guess this is the only way i.e., GROUP_CONCAT
回答3:
You can try something like this piece:
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
Tryed here works fine!
回答4:
Not sure how many groups you will be having but if its a finiate number I would suggest that you create a column for each group or use the mysql data type SET (bit masking).
回答5:
I'm not sure if this is the way you do things (as I'm quite new here) but if that's the example you're using wouldn't it be easier to have the columns user, IN_A, IN_B and IN_C? Especially since that way you wouldn't be repeating the user data again
来源:https://stackoverflow.com/questions/3725944/is-there-any-mysql-aggregate-function-for-contains