2013-08-22 166 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;