如何在mysql中编写hasmanythrough关系查询?

ffvjumwh  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(387)

在mysql中,为hasmanythrough关系编写查询的正确方法是什么?
例如,我有5张table。它们是a、b、c、d、e。a与c到b有hasmany关系,a与e到d也有hasmany关系。
示例的模式

  1. CREATE TABLE `a` (
  2. `id` varchar(36) NOT NULL,
  3. `name` tinytext NOT NULL,
  4. PRIMARY KEY (`id`),
  5. UNIQUE KEY `id_UNIQUE` (`id`)
  6. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  7. CREATE TABLE `c` (
  8. `id` varchar(36) NOT NULL,
  9. `name` varchar(90) NOT NULL,
  10. PRIMARY KEY (`id`),
  11. UNIQUE KEY `id_UNIQUE` (`id`)
  12. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  13. CREATE TABLE `b` (
  14. `id` int(11) NOT NULL,
  15. `aId` varchar(36) NOT NULL,
  16. `cId` varchar(36) NOT NULL,
  17. PRIMARY KEY (`id`),
  18. KEY `fk_a_idx` (`aId`),
  19. KEY `fk_c_idx` (`cId`),
  20. CONSTRAINT `fk_cId` FOREIGN KEY (`cId`) REFERENCES `c` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  21. CONSTRAINT `fk_aId` FOREIGN KEY (`aId`) REFERENCES `a` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  22. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  23. CREATE TABLE `e` (
  24. `id` varchar(36) NOT NULL,
  25. `name` varchar(90) NOT NULL,
  26. PRIMARY KEY (`id`),
  27. UNIQUE KEY `id_UNIQUE` (`id`)
  28. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  29. CREATE TABLE `d` (
  30. `id` int(11) NOT NULL,
  31. `aId` varchar(36) NOT NULL,
  32. `eId` varchar(36) NOT NULL,
  33. PRIMARY KEY (`id`),
  34. KEY `fk_aa_idx` (`aId`),
  35. KEY `fk_e_idx` (`eId`),
  36. CONSTRAINT `fk_eId` FOREIGN KEY (`eId`) REFERENCES `e` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  37. CONSTRAINT `fk_aaId` FOREIGN KEY (`aId`) REFERENCES `a` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
  38. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  39. INSERT into a(id, name) values ('123', 'name');
  40. insert into c(id, name) values ('1', 'name');
  41. insert into c(id, name) values ('2', 'name2');
  42. insert into c(id, name) values ('3', 'name3');
  43. insert into b(id, aId, cId) values (1, '123', '1');
  44. insert into b(id, aId, cId) values (2, '123', '2');
  45. insert into b(id, aId, cId) values (3, '123', '3');
  46. insert into e(id, name) values ('1', '1name');
  47. insert into d(id, aId, eId) values (1, '123', '1');

还有一把同样的小提琴
http://sqlfiddle.com/#!9/1e31b7/1号
我想使用1个查询从a中获取一行数据,该数据与c和e中的行相关,其中的数据由b和d连接。
这是我的尝试

  1. select a.*,
  2. group_concat(lfc.id)
  3. group_concat(lfc.name)
  4. group_concat(lfe.id)
  5. group_concat(lfe.name)
  6. from a,
  7. left join (
  8. select c.id, c.name, b.aId
  9. from b left join c on b.cId=c.id
  10. where b.aId=123
  11. ) as lfc on lfc.aId=123
  12. left join (
  13. select e.id, e.name, d.aId
  14. from d left join e on d.eId=e.id
  15. where d.aId=123
  16. ) as lfe on lfe.aId=123
  17. where a.id=123 group by a.id

使用此查询将导致问题。如果b中有2行,它将使d中的数据多了一个副本,这不是我想要的。
字段组concat(lfe.id)中的数据应该只包含一个数据,这是数据库中的真实情况,而不是三个。这可以通过使用多个查询轻松完成,但我正在寻找任何可能的方法,只使用一个查询来获得相同的结果。
有没有人知道如何改进这个查询,或者有没有人建议用正确的方式编写查询?

k5ifujac

k5ifujac1#

我怀疑这可以让a.id定位整个查询:

  1. SELECT a.*,
  2. group_concat(c.id)
  3. group_concat(c.name)
  4. group_concat(e.id)
  5. group_concat(e.name)
  6. FROM a
  7. LEFT JOIN b ON a.id = b.aId
  8. JOIN c ON b.cId = c.id
  9. LEFT JOIN d ON a.id = d.aId
  10. JOIN e ON d.eId = e.id
  11. WHERE a.id=123
  12. GROUP BY a.id

相关问题