MySQL与group_concat一起离开了

时间:2013-08-22 18:43:40

标签: mysql left-join 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     |
+-------+-------+--------+

2 个答案:

答案 0 :(得分:4)

您基本上错过了GROUP BYGROUP_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`

An SQLfiddle with the correction

答案 1 :(得分:0)

您的查询的主要问题是您没有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;