简体   繁体   中英

MySQL - is it possible to use group_concat in an IN() statement?

I've been trying to use "group_concat" to build a list of values for use in IN(), but even carefully crafting a comma delimited, single-quoted value string doesn't seem to work. The following does not "find" "fr" in the group_concat'ed list, even though the displayed value for the group_concat is 'de','es','fr', and a result set of one record is incorrectly returned;

SELECT Message, table_id FROM Tenant
LEFT JOIN Translation on Translation.table_id=Tenant.ID
WHERE table_name='Tenant' AND table_column='Message' AND Tenant.ID=2
GROUP BY table_name, table_column, table_id HAVING 'fr' NOT 
IN(group_concat(CONCAT('''', language, '''')));

Whereas below, "fr" IS indeed found and the resultset is appropriately empty:

SELECT Message, table_id FROM Tenant
LEFT JOIN Translation on Translation.table_id=Tenant.ID
WHERE table_name='Tenant' AND table_column='Message' AND Tenant.ID=2
GROUP BY table_name, table_column, table_id HAVING 'fr' NOT IN('de','es','fr')

I realize I can use LOCATE();

SELECT Message, table_id FROM Tenant
LEFT JOIN Translation on Translation.table_id=Tenant.ID
WHERE table_name='Tenant' AND table_column='Message' AND Tenant.ID=2
GROUP BY table_name, table_column, table_id HAVING LOCATE('de', 
group_concat(language)) = 0

But such a text search is likely less efficient compared to "IN()", which is likely scheduled differently by the MySQL optimizer.

I've tried every trick I'm aware of (cast(), trying to reconstitute the list, etc) and I'm fresh out. I'm not sure if this is a limit of group_concat, or perhaps even a "bug" in MySQL compiler. If anyone has any good ideas, I'd be most appreciative.

Thanks

You should be using conditional aggregation in your HAVING clause to check for the French language string:

SELECT
    table_id
FROM Tenant
LEFT JOIN Translation
    ON Translation.table_id = Tenant.ID
WHERE
    table_name = 'Tenant' AND
    table_column = 'Message' AND
    Tenant.ID = 2
GROUP BY
    table_id
HAVING SUM(CASE WHEN language = 'fr' THEN 1 ELSE 0 END) = 0

Note that I removed the table_name and table_column from the GROUP BY list, because you specify fixed values for these columns in the WHERE clause. Also, I removed Message from the SELECT list because it does not appear in the group by nor is it inside an aggregate function. Your original query would not even run on certain versions of MySQL or most other databases.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM