Как написать запрос для отношений hasManyThrough в MySQL?

0

Каков правильный способ писать запросы для hasManyThrough отношения в Mysql?

Например, у меня есть 5 таблиц. Это a, b, c, d, e. a имеет hasMany отношение с c через b, a также имеет отношение Many с e через d.

Схема примера

CREATE TABLE 'a' (
  'id' varchar(36) NOT NULL,
  'name' tinytext NOT NULL,
  PRIMARY KEY ('id'),
  UNIQUE KEY 'id_UNIQUE' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


CREATE TABLE 'c' (
  'id' varchar(36) NOT NULL,
  'name' varchar(90) NOT NULL,
  PRIMARY KEY ('id'),
  UNIQUE KEY 'id_UNIQUE' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE 'b' (
  'id' int(11) NOT NULL,
  'aId' varchar(36) NOT NULL,
  'cId' varchar(36) NOT NULL,
  PRIMARY KEY ('id'),
  KEY 'fk_a_idx' ('aId'),
  KEY 'fk_c_idx' ('cId'),
  CONSTRAINT 'fk_cId' FOREIGN KEY ('cId') REFERENCES 'c' ('id') ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT 'fk_aId' FOREIGN KEY ('aId') REFERENCES 'a' ('id') ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE 'e' (
  'id' varchar(36) NOT NULL,
  'name' varchar(90) NOT NULL,
  PRIMARY KEY ('id'),
  UNIQUE KEY 'id_UNIQUE' ('id')
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE 'd' (
  'id' int(11) NOT NULL,
  'aId' varchar(36) NOT NULL,
  'eId' varchar(36) NOT NULL,
  PRIMARY KEY ('id'),
  KEY 'fk_aa_idx' ('aId'),
  KEY 'fk_e_idx' ('eId'),
  CONSTRAINT 'fk_eId' FOREIGN KEY ('eId') REFERENCES 'e' ('id') ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT 'fk_aaId' FOREIGN KEY ('aId') REFERENCES 'a' ('id') ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT into a(id, name) values ('123', 'name');
insert into c(id, name) values ('1', 'name');
insert into c(id, name) values ('2', 'name2');
insert into c(id, name) values ('3', 'name3');
insert into b(id, aId, cId) values (1, '123', '1');
insert into b(id, aId, cId) values (2, '123', '2');
insert into b(id, aId, cId) values (3, '123', '3');
insert into e(id, name) values ('1', '1name');
insert into d(id, aId, eId) values (1, '123', '1');

и sqlfiddle того же

http://sqlfiddle.com/#!9/1e31b7/1

Я хочу использовать 1 запрос, чтобы получить строку данных из a, и данные связаны с строкой в c и e, данные которой связаны b и d.

Вот моя попытка

select a.*,
    group_concat(lfc.id)
    group_concat(lfc.name)
    group_concat(lfe.id)
    group_concat(lfe.name)
from a,
    left join (
        select c.id, c.name, b.aId
        from b left join c on b.cId=c.id
        where b.aId=123
    ) as lfc on lfc.aId=123
    left join (
        select e.id, e.name, d.aId
        from d left join e on d.eId=e.id
        where d.aId=123
    ) as lfe on lfe.aId=123
where a.id=123 group by a.id 

Используя этот запрос, это вызовет проблему. Если в b есть 2 строки, это приведет к тому, что данные из d будут иметь еще одну копию, которая не то, что я хотел.

Данные в поле group_concat (lfe.id) должны содержать только одну информацию, которая является реальной ситуацией в базе данных, а не три. Это можно сделать легко, используя несколько запросов, но я ищу любой возможный способ использовать только один запрос для получения того же результата.

Кто-нибудь имеет представление о том, как улучшить этот запрос или какое-либо предложение правильно написать запрос?

  • 0
    См. Meta.stackoverflow.com/questions/333952/… . Кроме того, на мой взгляд, в SQL нет проблемы, для которой GROUP_CONCAT должна быть частью решения.
  • 0
    @Strawberry Спасибо, что поделились ссылкой.
Показать ещё 3 комментария
Теги:

1 ответ

0

Я подозреваю, что это может заставить оставить a.id в WHERE, чтобы привязать весь запрос:

SELECT a.*,
    group_concat(c.id)
    group_concat(c.name)
    group_concat(e.id)
    group_concat(e.name)
FROM a
LEFT JOIN b ON a.id = b.aId
JOIN c ON b.cId = c.id
LEFT JOIN d ON a.id = d.aId
JOIN e ON d.eId = e.id
WHERE a.id=123
GROUP BY a.id

Ещё вопросы

Сообщество Overcoder
Наверх
Меню