Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有5个表的复杂SQL连接_Sql_Join_Create Table - Fatal编程技术网

具有5个表的复杂SQL连接

具有5个表的复杂SQL连接,sql,join,create-table,Sql,Join,Create Table,我正在开发一个相对庞大的应用程序,其中包含很多表。我必须编写一个SQL查询,经过简化后,它涉及5个表(参见jpg中的连接) 其思路如下: 人有地址,地址类型有private、pro等和country。 个人也可以有选择。此处所示的选项表中带有名称\ id的这些选项可以链接到地址类型 这样做的目的是提取所有拥有一个或多个地址的人,这些地址由一个国家指定,并且他们也出现在[选项地址]表中 例如,假设我们想要地址为country_id=1的人。结果集必须排除没有链接到其选项的相同地址类型的人员 嗯。。

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

其思路如下: 人有地址,地址类型有private、pro等和country。 个人也可以有选择。此处所示的选项表中带有名称\ 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


我不确定我是否完全理解你想要的结果。当国家/地区为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;
还有


祝你好运。

+1用于创建表脚本,插入数据以便人们可以使用它。好东西如果country=1,你想要的结果是什么-哪些人应该返回?总是很高兴有一个表创建脚本,特别是FK引用。我个人更喜欢“非关键”列,只是举个例子。用于RDBMS的mySQL。。。不过,我认为您的数据库模式放在一起很笨拙。除其他事项外,地址记录的存在是否意味着地址选项的存在?是否可以删除该表?option.name\u id指的是什么?选项\u address\u type.type\u id指的是什么?name\u id是指向其他表的链接,我在这里没有描述。不,一个人只能有一个没有选择的地址。但是一个人可以有一个选项,可以链接到地址类型。正如发条缪斯所说,这个模式有点笨拙。我现在正试图重新思考整个事情,即使这意味着要重新编写应用程序的很大一部分。但是谢谢你的帮助!如果,最后,这个当前版本仍然是最好的,我肯定会重新打开这个问题,如果我没有找到如何编写这个sql!谢谢你!这是否适用于MySQL?因为我在FROM子句上有一个语法错误。似乎不支持逗号分隔的表…选项需要用单引号括起来,因为它在MySQL中是一个保留字…我还添加了SQL 92语法。谢谢!我现在必须离开,但我明天会尝试使用您的sql,并在需要时更好地解释预期结果。
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;