Domanda

I have a SQL Fiddle with the table creation and query that I'm having issues with: http://www.sqlfiddle.com/#!9/3404e/1

Here is the table creation script:

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);

Here is the query I'm trying to run:

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';

What I'm expecting are two rows as follows:

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

But I'm only receiving the state row. If I remove the group_concat line I get the three lines as follows, so I know everything is getting returned:

+-------+-------+--------+
| name  | label | option |
+-------+-------+--------+
| name  | Name  | NULL   |
| state | State | CO     |
| state | State | NE     |
+-------+-------+--------+
È stato utile?

Soluzione

You're basically missing a GROUP BY, GROUP_CONCAT() concatenates all values in a group and without a GROUP BY there's only one group.

Try this;

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.

Altri suggerimenti

The major issue with your query is that you do not have a group by clause.

In addition, your where conditions are "undoing" the left joins, turning them into inner joins. The following accomplishes what you want:

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top