MySQL LIKE from JOIN, а GROUP_CONCAT возвращает только одну строку из объединенной таблицы.

У меня есть 3 таблицы: регионы, недвижимость и таблица realestate_regions "один ко многим".
Мне нужно найти недвижимость по адресу. У меня следующий запрос выбора:

SELECT re.id, GROUP_CONCAT( r.name ) AS address
FROM realestate re 
JOIN realestate_regions rr ON re.id = rr.reid 
LEFT JOIN regions r ON rr.rid = r.id 
WHERE ( re.id LIKE 'san%' OR r.name LIKE 'san%') 
GROUP BY re.id;

Это дает мне следующий результат:

+----+---------------+
| id | address       |
+----+---------------+
|  1 | San Francisco |
+----+---------------+

Но мне нужно:

+----+------------------------+
| id | address                |
+----+------------------------+
|  1 | USA, CA, San Francisco |
+----+------------------------+

Запрос возвращает только соответствующую строку из таблицы регионов, а не всю, что логично из-за условия LIKE. Поэтому я включил отдельный JOIN для подобных условий.

SELECT re.id, GROUP_CONCAT( r.name ) AS address
FROM realestate re 
JOIN realestate_regions rr ON re.id = rr.reid 
LEFT JOIN regions r ON rr.rid = r.id 
LEFT JOIN regions r2 ON rr.rid = r2.id 
WHERE ( re.id LIKE 'san%' OR r2.name LIKE 'san%') 
GROUP BY re.id;

Надеясь, что это сохранит первый JOIN и его GROUP_CONCAT со всеми строками и выполнит условие только во втором JOIN, но нет, я получаю точно такой же результат.
Как я могу получить полный адрес и иметь возможность фильтровать результаты с помощью НРАВИТСЯ условие?

Таблицы:

CREATE TABLE `realestate` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `random_data` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `regions` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `realestate_regions` (
    `rid` int(11) unsigned NOT NULL,
    `reid` int(11) unsigned NOT NULL,
    PRIMARY KEY (`rid`,`oid`),
    CONSTRAINT `realestate_regions_ibfk_2` FOREIGN KEY (`reid`) REFERENCES `realestate` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
    CONSTRAINT `realestate_regions_ibfk_1` FOREIGN KEY (`rid`) REFERENCES `regions` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;

Примеры данных:

Таблица1: недвижимость. Основная таблица с большей частью данных. Столбцов намного больше, но я исключил их из примера для ясности.

+----+--------------+
| id | random_data  |
+----+--------------+
|  1 | object A     |
|  2 | object B     |
+----+--------------+

Таблица2: регионы. Эта таблица состоит из различных адресных строк.

+----+---------------+
| id | name          |
+----+---------------+
|  1 | USA           |
|  2 | CA            |
|  3 | San Francisco |
|  4 | Los Angeles   |
+----+---------------+

Таблица3: realestate_regions. Таблица "один ко многим", соединяющая адресные строки с объектом.

+-----+-----+
| rid | reid|
+-----+-----+
|   1 |   1 |
|   2 |   1 |
|   3 |   1 |
|   1 |   2 |
|   2 |   2 |
|   4 |   2 |
+-----+-----+

person ruuter    schedule 25.06.2014    source источник
comment
Как вы можете ожидать получить USA, CA, Los Angeles , если ваше предложение where равно like '%san%'? и как узнать, какой ПОРЯДОК применить к группе concat?   -  person xQbert    schedule 25.06.2014
comment
Срай, вы правы, но это всего лишь пример ошибки. Я починил это. Остается вопрос. Я не уверен, что вы имеете в виду под каким порядком.   -  person ruuter    schedule 25.06.2014
comment
USA, CA, San Francisco CA, San Francisco, USA San FranCisco, USA, CA Что движет порядком, в котором они представлены, кроме человеческого логического понимания. в данных нет ничего, что могло бы обозначить порядок, который я могу видеть ...   -  person xQbert    schedule 25.06.2014
comment
ах да, ну, в таблице реальных регионов у меня также есть parent_id, но я не думал, что это нужно для примера, так как это не должно ничего менять.   -  person ruuter    schedule 25.06.2014


Ответы (1)


Проблема в том, что вам нужно, где должно произойти после объединения группы. Это один из способов использования подвыбора.

Select * from (
    SELECT re.id, GROUP_CONCAT( r.name ) AS address
    FROM realestate re 
    JOIN realestate_regions rr 
      ON re.id = rr.reid 
    LEFT JOIN regions r 
      ON rr.rid = r.id 
    GROUP BY re.id) b
    WHERE (Address LIKE '%san%') 

Другим ... и более стандартным было бы использование наличия, которое применяется после вычисления совокупности.

    SELECT re.id, GROUP_CONCAT( r.name ) AS address
    FROM realestate re 
    JOIN realestate_regions rr 
      ON re.id = rr.reid 
    LEFT JOIN regions r 
      ON rr.rid = r.id 
    GROUP BY re.id 
    Having address like '%san%' 

Я до сих пор не могу подтвердить, что порядок group_concat будет согласованным при обнаружении нескольких записей.

person xQbert    schedule 25.06.2014
comment
хм, да, это начинает иметь смысл, но, к сожалению, оба возвращают Empty set :( - person ruuter; 25.06.2014
comment
ах, нашел ошибку. В ваших запросах это должно быть "% san%", а не "san%". - person ruuter; 25.06.2014
comment
Обновлен и прокомментирован порядок group_cocnat - person xQbert; 25.06.2014
comment
Сделав свое дело. Заказ тоже в порядке. Я оставил это из примера, потому что вопрос уже слишком длинный. В любом случае, в реальном коде гораздо больше. Благодарю вас! - person ruuter; 25.06.2014