2013-08-22 134 views
0

加入我有一个SQL拨弄表的创建和查询我遇到的问题:http://www.sqlfiddle.com/#!9/3404e/1的MySQL留下GROUP_CONCAT

下面是表创建脚本:

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

回答

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

0

您查询的主要问题是您没有group by子句。

此外,您的where条件是“撤消”left join s,将它们变成inner join s。以下完成你想要的:

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;