MySQL使用IN / FIND_IN_SET读取子查询中的多行

时间:2012-01-17 18:51:29

标签: mysql subquery in-subquery

我有两个表,位置和位置组

CREATE TABLE locations (
    location_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(63) UNIQUE NOT NULL
);

INSERT INTO locations (name)
  VALUES
('london'),
('bristol'),
('exeter');

CREATE TABLE location_groups (
    location_group_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    location_ids VARCHAR(255) NOT NULL,
    user_ids VARCHAR(255) NOT NULL,
    name VARCHAR(63) NOT NULL,
);

INSERT INTO location_groups (location_ids, user_ids, name)
  VALUES
('1', '1,2,4', 'south east'),
('2,3', '2', 'south west');

我要做的是返回给定user_id所在的所有location_groups的所有location_ids。我正在使用CSV将location_ids和user_ids存储在location_groups表中。我知道这不是规范化的,但这就是数据库的方式,而且它不受我的控制。

我目前的查询是:

SELECT location_id 
  FROM locations 
  WHERE FIND_IN_SET(location_id, 
      (SELECT location_ids 
         FROM location_groups 
         WHERE FIND_IN_SET(2,location_groups.user_ids)) )

现在这可以正常工作,例如user_id = 1(因为只返回1个location_group行),但如果我搜索user_id = 2,我得到一个错误,说子查询返回超过1行,这是预期的因为用户2在2个location_groups中。我理解为什么错误被抛出,我正试图找出解决方法。

为了澄清在location_groups.user_ids中搜索user_id 1时,应返回location_id 1。搜索user_id 2时,应返回location_ids 1,2,3。

我知道这是一个复杂的查询,所以如果有什么不清楚,请告诉我。任何帮助,将不胜感激!谢谢。

1 个答案:

答案 0 :(得分:2)

您可以使用GROUP_CONCAT合并子查询中的location_id

SELECT location_id 
FROM locations 
WHERE FIND_IN_SET(location_id, 
    (SELECT GROUP_CONCAT(location_ids)
     FROM location_groups 
     WHERE FIND_IN_SET(2,location_groups.user_ids)) )

或者,使用编写查询的问题作为规范化为什么好的一个例子。哎呀,即使你使用这个查询,它的运行速度也会慢于对正确规范化表的查询;您可以使用它来显示为什么要重组表格。