1

这是三个表的结构:

CREATE TABLE `contacts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(99) DEFAULT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

CREATE TABLE `addresses` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `street` varchar(99) DEFAULT NOT NULL,
  `city` varchar(99) DEFAULT NOT NULL,
  `state` varchar(20) DEFAULT NOT NULL,
  `zip` int(9) DEFAULT NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

CREATE TABLE `contacts_addresses` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `idcontact` int(9) DEFAULT NOT NULL,
  `idaddress` int(9) DEFAULT NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;

样本数据:

mysql> select * from contacts;
+----+----------------+
| id | name           |
+----+----------------+
|  1 | hank kingsley  |
|  2 | phil collins   |
|  3 | sam weisgamgee |
|  4 | john johnson   |
|  5 | dale girdley   |
+----+----------------+

mysql> SELECT * FROM addresses;
+----+--------------------+-----------+-------+-------+
| id | street             | city      | state | zip   |
+----+--------------------+-----------+-------+-------+
|  1 | rainbow lane       | fairytown | VT    | 52689 |
|  2 | townie ave         | manhattan | NY    | 98569 |
|  3 | sayitain'tso drive | oldsville | KY    | 25689 |
|  4 | somehow circle     | Anytown   | TX    | 84757 |
+----+--------------------+-----------+-------+-------+

mysql> select * from contacts_addresses;
+----+-----------+-----------+
| id | idcontact | idaddress |
+----+-----------+-----------+
|  1 |         3 |         1 |
|  2 |         3 |         2 |
|  3 |         5 |         3 |
|  4 |         1 |         1 |
|  5 |         4 |         2 |
+----+-----------+-----------+

我正在尝试运行一个查询,让我指定一个唯一联系人的 ID,并提取他们的关联地址。几天来我一直试图弄清楚这一点,但我只是不明白连接是如何工作的。其他论坛、文章、资料并没有帮助我阐明这个特定问题。

我是否正确构建表格?我应该在某处使用外键吗?我是否为关联表/列使用了适当的命名约定?

任何帮助表示赞赏,无论是解决方案还是显示查询结构的伪代码 - 谢谢。

4

5 回答 5

4

要获取某个特定联系人的所有地址,请说 concatid 3,您可以执行以下操作

select 
c.id,
c.name,
a.street,
a.city,
a.zip,
a.state
from contacts_addresses ca
join contacts c on c.id = ca.idcontact
join addresses a on a.id = ca.idaddress
where c.id = 3 

要获取所有联系人,只需删除最后一个 where 条件``

于 2014-06-27T04:06:11.743 回答
2
SELECT C.id, C.name, A.street, A.city, A.state, A.zip
FROM contacts_addresses CA
INNER JOIN contacts C ON C.id = CA.idcontact
INNER JOIN addresses A ON A.id = CA.idaddress;

SQL Fiddle

于 2014-06-27T04:05:02.840 回答
0

您的数据结构是正确的,并且使用地址和联系人表之间的映射表是一个很好的方法。我唯一的评论是contact_idandaddress_id可能是比idcontactand更合适的列名idaddress,但这取决于您,它可以正常工作。

您可以使用连接来实现这种关系。左连接将返回联系人,即使它与任何其他表记录都不匹配,或者您可以使用内连接仅在每个表中找到匹配项时才返回它。

SELECT
    C.*,
    A.*
FROM contacts C
LEFT JOIN contacts_addresses CA
    ON CA.idcontact = C.id
LEFT JOIN address A
    ON CA.idaddress = A.id
于 2014-06-27T04:04:26.140 回答
0

又一个例子。看来两个人是室友?

select a.name, c.street, c.city, c.state, c.zip
from contacts a
join contacts_addresses b on a.id = b.idcontact
join addresses c on b.idaddress = c.id;

小提琴

于 2014-06-27T04:05:27.443 回答
0

您需要使用内部联接来解决您的问题,对此的适当查询将是

SELECT con.name, addr.street, addr.state, addr.zip
from contacts_addresses
inner join contacts con
on con.id = contacts_addresses.idcontact
inner join addresses addr
on addr.id = contacts_addresses.idaddress 
于 2014-06-27T04:06:32.810 回答