MySQL вышел из соединения с group_concat

У меня есть скрипт SQL с созданием таблицы и запросом, с которым у меня возникают проблемы: http://www.sqlfiddle.com/#!9/3404e/1

Вот скрипт создания таблицы:

CREATE TABLE IF NOT EXISTS `collection` (
  `id` bigint(20) unsigned NOT NULL,
  `name` varchar(50) NOT NULL,
  `label` varchar(120) NOT NULL,
  `label_plural` varchar(120) NOT NULL);

INSERT INTO `collection` (`id`, `name`, `label`, `label_plural`) VALUES
    (1, 'account', 'Account', 'Accounts');

CREATE TABLE IF NOT EXISTS `field` (
  `id` bigint(20) unsigned NOT NULL,
  `name` varchar(50) NOT NULL,
  `label` varchar(120) NOT NULL,
  `collection_id` bigint(20) unsigned NOT NULL);

INSERT INTO `field` (`id`, `name`, `label`, `collection_id`) VALUES
    (1, 'name', 'Name', 1),
    (2, 'state', 'State', 1);

CREATE TABLE IF NOT EXISTS `option` (
  `id` bigint(20) unsigned NOT NULL,
  `record_type_id` bigint(20) unsigned DEFAULT NULL,
  `field_id` bigint(20) unsigned NOT NULL,
  `value` varchar(120) NOT NULL);

INSERT INTO `option` (`id`, `record_type_id`, `field_id`, `value`) VALUES
    (1, NULL, 2, 'CO'),
    (2, NULL, 2, 'NE'),
    (3, NULL, 2, 'BC'),
    (4, NULL, 2, 'MB'),
    (5, 1, 2, 'CO'),
    (6, 1, 2, 'NE'),
    (7, 2, 2, 'BC'),
    (8, 2, 2, 'MB');

CREATE TABLE IF NOT EXISTS `record_type` (
  `id` bigint(20) unsigned NOT NULL,
  `name` varchar(120) NOT NULL,
  `collection_id` bigint(20) unsigned NOT NULL);

INSERT INTO `record_type` (`id`, `name`, `collection_id`) VALUES
    (1, 'US', 1),
    (2, 'Canada', 1);

Вот запрос, который я пытаюсь запустить:

select
    `field`.`name`,
    `field`.`label`,
    ifnull(group_concat(`option`.`value` separator ';'), '') as `options`
from
    `field`
join
    `collection` on
        `collection`.`id` = `field`.`collection_id`
join
    `record_type` on
        `record_type`.`collection_id` = `collection`.`id`
left join
    `option` on
        `option`.`record_type_id` = `record_type`.`id` and
        `option`.`field_id` = `field`.`id`
where
    `record_type`.`name` = 'US' and
    `collection`.`name` = 'account';

Я ожидаю две строки следующим образом:

+-------+-------+---------+
| name  | label | options |
+-------+-------+---------+
| name  | Name  | NULL    |
| state | State | CO;NE   |
+-------+-------+---------+

Но я получаю только строку состояния. Если я удалю строку group_concat, я получу три строки следующим образом, поэтому я знаю, что все возвращается:

+-------+-------+--------+
| name  | label | option |
+-------+-------+--------+
| name  | Name  | NULL   |
| state | State | CO     |
| state | State | NE     |
+-------+-------+--------+

person travis.paxton    schedule 22.08.2013    source источник


Ответы (2)


В основном вам не хватает GROUP BY, GROUP_CONCAT() объединяет все значения в группе, а без GROUP BY есть только одна группа.

Попробуй это;

select
    `field`.`name`, `field`.`label`,
    group_concat(`option`.`value` separator ';') as `options`
from `field`
join `collection` 
  on `collection`.`id` = `field`.`collection_id`
join `record_type` 
  on `record_type`.`collection_id` = `collection`.`id`
left join `option` 
  on `option`.`record_type_id` = `record_type`.`id` 
 and `option`.`field_id` = `field`.`id`
where `record_type`.`name` = 'US' 
  and `collection`.`name` = 'account'
GROUP BY `field`.`name`,`field`.`label`

SQLfiddle с исправлением.

person Joachim Isaksson    schedule 22.08.2013

Основная проблема с вашим запросом заключается в том, что у вас нет предложения group by.

Кроме того, ваши условия where "отменяют" left join, превращая их в inner join. Следующее выполняет то, что вы хотите:

select
    `field`.`name`,
    `field`.`label`,
    ifnull(group_concat(`option`.`value` separator ';'), '') as `options`
from
    `field`
join
    `collection` on
        `collection`.`id` = `field`.`collection_id` and
        `collection`.`name` = 'account'
join
    `record_type` on
        `record_type`.`collection_id` = `collection`.`id` and
        `record_type`.`name` = 'US' 
left join
    `option` on
        `option`.`record_type_id` = `record_type`.`id` and
        `option`.`field_id` = `field`.`id`
group by field.name, field.label;
person Gordon Linoff    schedule 22.08.2013