我有以下设置:
[客户]:id
(ai),name
(文字),regions
(文字);
[地区]:id
(ai - 与[自治市]中的region_id
相关),name
(文字);
[市政]:id
(ai - 与[邮件]中的municipality_id
相关),姓名(文本),region_id
(int);
[邮政]:id
(ai),name
(文字),municipality_id
(int)。
[clients]中的regions
列包含“1”,“1,2”或“1,3,7”之类的字符串。
现在,一般的想法是有人输入邮政名称的特定值,并且当邮政编码落入特定区域时返回客户名称。每个市都属于特定区域,每个邮政编码属于特定的市政当局。客户可以在多个地区工作。
我有以下查询:
select name from clients where find_in_set((select region_id from municipalities where id = (select municipality_id from postals where name = "string")),(select regions from clients)) != 0
但我一直得到#1242 - Subquery返回超过1行,我不知道为什么。搜索到的字符串应该只返回1个municipality_id,而后者只返回1个region_id,只能在[clients]表的regions
字符串中找到一个。
我在这里缺少什么?
答案 0 :(得分:0)
这样的事情应该有用,虽然我还没有测试过。
SELECT DISTINCT c.name
FROM clients AS c
JOIN municipalities AS m
ON FIND_IN_SET(m.region_id, c.regions)
JOIN postals AS p
ON m.id = p.municipality_id
WHERE p.name = 'string';
这不是FIND_IN_SET()的预期用途。该函数应该用于匹配MySQL SET data type中的值。它也适用于匹配逗号分隔的字符串,但它不适合SQL。
对逗号分隔列表使用FIND_IN_SET()必然会进行表扫描,因此无法使用索引进行优化。如果希望查询具有更好的性能,则不应将多值属性存储为逗号分隔的字符串。
对于使用逗号分隔字符串的其他不良影响,请参阅我对Is storing a delimited list in a database column really that bad?
的回答多值属性属于子表,每行一个值,以及对市政当局的引用。然后,您可以使用联接进行搜索,并且您有机会创建索引以优化查询。