2012-01-17 3 views
1

У меня есть две таблицы, места и группа местоположенийMySQL с помощью IN/FIND_IN_SET прочитать несколько строк в подзапросе

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'); 

То, что я пытаюсь сделать, это вернуть все location_ids для всех location_groups где данный user_id существует. Я использую 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. Я понимаю, почему возникает ошибка, я пытаюсь решить, как ее решить.

Чтобы уточнить при поиске user_id 1 в location_groups.user_ids, необходимо вернуть location_id 1. При поиске user_id 2 должно быть возвращено location_ids 1,2,3.

Я знаю, что это сложный запрос, поэтому, если что-то неясно, просто дайте мне знать. Любая помощь будет оценена! Спасибо.

+0

Не сдавайтесь! Борьба за нормализацию! – outis

+1

Правильный [пример кода] (http://sscce.org/) (здесь, операторы SQL) более полезен, чем любой формат ad hoc и образец данных. Пожалуйста, используйте 'CREATE TABLE' и' INSERT ... VALUES' для образцов. Желаемые результаты не обязательно должны быть представлены в качестве примера кода, так как результаты - это результат кода, а не самого кода. – outis

ответ

2

Вы можете использовать GROUP_CONCAT для объединения location_id s в подзапрос.

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))) 

В качестве альтернативы, используйте проблемы с написанием запроса в качестве примера того, почему нормализация является хорошей. Heck, даже если вы используете этот запрос, он будет работать медленнее, чем запрос на правильно нормализованные таблицы; вы можете использовать это, чтобы показать, почему таблицы должны быть реструктурированы.

+0

Это прекрасно, именно то, что мне нужно! Спасибо. – leejmurphy

Смежные вопросы