繁体   English   中英

复杂SQL加入5个表

[英]Complex SQL Join with 5 tables

我正在开发一个相对庞大的应用程序,它包含了很多表。 我必须编写一个SQL查询,在简化后涉及5个表(参见jpg的连接)。

这个想法如下:人有地址,地址有类型(私人,专业等)和国家。 人们也可以选择。 这些选项(在带有name_id的选项表中显示)可以链接到地址类型。

这个想法是提取所有具有一个或多个地址的人,这些地址由国家指定,并且它们也出现在[选项地址]表中。

例如,假设我们希望拥有country_id = 1的地址的人。 结果集必须排除没有与其选项相关联的地址类型的人员。

嗯......我不确定我理解自己:)

但无论如何,这是创建所有东西的SQL。

CREATE TABLE `address` (
  `person_id` int(11) NOT NULL,
  `type_id` int(11) NOT NULL,
  `country_id` int(11) NOT NULL,
  UNIQUE KEY `apt` (`person_id`,`type_id`),
  KEY `apid` (`person_id`),
  KEY `atid` (`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `address` (`person_id`, `type_id`, `country_id`) VALUES
(1, 1, 1),
(2, 2, 1),
(3, 1, 1),
(3, 2, 2),
(5, 1, 2),
(6, 2, 1),
(7, 1, 1),
(7, 2, 2),
(8, 1, 1),
(9, 2, 1);

CREATE TABLE `address_type` (
  `id` int(11) NOT NULL,
  UNIQUE KEY `tid` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `address_type` (`id`) VALUES
(1),
(2);

CREATE TABLE `option` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name_id` int(11) NOT NULL,
  `person_id` int(11) NOT NULL,
  UNIQUE KEY `oid` (`id`),
  UNIQUE KEY `onp` (`name_id`,`person_id`),
  KEY `opid` (`person_id`),
  KEY `on` (`name_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

INSERT INTO `option` (`id`, `name_id`, `person_id`) VALUES
(1, 1, 1),
(2, 1, 2),
(3, 1, 3),
(4, 1, 5),
(5, 1, 6),
(6, 1, 7),
(7, 1, 8),
(8, 1, 9);

CREATE TABLE `option_address_type` (
  `option_id` int(11) NOT NULL,
  `type_id` int(11) NOT NULL,
  UNIQUE KEY `ot` (`option_id`,`type_id`),
  KEY `ooid` (`option_id`),
  KEY `otid` (`type_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `option_address_type` (`option_id`, `type_id`) VALUES
(1, 1),
(2, 2),
(3, 1),
(3, 2),
(4, 2),
(5, 1),
(6, 1),
(7, 1),
(7, 2),
(8, 1),
(8, 2);

CREATE TABLE `person` (
  `id` int(11) NOT NULL,
  UNIQUE KEY `pid` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `person` (`id`) VALUES
(1),
(2),
(3),
(4),
(5),
(6),
(7),
(8),
(9);


ALTER TABLE `address`
  ADD CONSTRAINT `address_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `address_ibfk_2` FOREIGN KEY (`type_id`) REFERENCES `address_type` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE `option`
  ADD CONSTRAINT `option_ibfk_1` FOREIGN KEY (`person_id`) REFERENCES `person` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

ALTER TABLE `option_address_type`
  ADD CONSTRAINT `option_address_type_ibfk_1` FOREIGN KEY (`option_id`) REFERENCES `option` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  ADD CONSTRAINT `option_address_type_ibfk_2` FOREIGN KEY (`type_id`) REFERENCES `address_type` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;

那这个呢:

select person_id
from   address adr
,      `option` opt
,      option_address_type opt_adt
where  adr.country_id = 1
and    opt.person_id = adr.person_id
and    opt_adt.option_id = opt.option_id
and    opt_adt.type_id = adr.type_id

要么

select person_id
from   address adr
inner join   `option` opt
  on     opt.person_id = adr.person_id
  and    adr.country_id = 1
inner join    option_address_type opt_adt
  on      opt_adt.option_id = opt.option_id
  and    opt_adt.type_id = adr.type_id

我不确定我完全理解你想要的结果是什么。 当国家/地区为1时,排除地址类型不等于选项地址类型的人员?

像这样的东西?

SELECT p.id
FROM Person p
    JOIN address a ON p.Id = a.Person_ID
    JOIN address_type at ON a.Type_ID = at.Id
    JOIN `option` o ON p.Id = o.person_Id
    JOIN option_address_type oat ON o.id = oat.option_id
WHERE a.country_id = 1 AND at.id <> oat.type_id;

SQL小提琴

祝好运。

好吧,正如Clockwork-Muse所说,架构有点笨拙。 我现在正试图重新思考整个事情,即使它意味着重新编写应用程序的大部分内容。

但谢谢你的帮助! 如果,最后,这个当前版本仍然是最好的,我肯定会重新打开这个问题,如果我没有找到如何写这个sql!

非常感谢

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM