在MariaDB中使用子查询和FIND_IN_SET函数

时间:2018-04-13 13:44:41

标签: mysql

我有以下设置:

[客户]:id(ai),name(文字),regions(文字); [地区]:id(ai - 与[自治市]中的region_id相关),name(文字); [市政]:id(ai - 与[邮件]中的municipality_id相关),姓名(文本),region_id(int); [邮政]:id(ai),name(文字),municipality_id(int)。

  • 所有id都是主键

[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字符串中找到一个。

我在这里缺少什么?

1 个答案:

答案 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?

的回答

多值属性属于子表,每行一个值,以及对市政当局的引用。然后,您可以使用联接进行搜索,并且您有机会创建索引以优化查询。