使用MYSQL关联表和JOIN

时间:2014-06-27 04:00:52

标签: mysql join associative-table

这是三个表的结构:

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,并拉出他们的相关地址。我已经试图解决这个问题几天了,但我只是不明白联合是如何运作的。其他论坛,文章,材料避风港帮助我阐明了这个特殊问题。

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

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

5 个答案:

答案 0 :(得分: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 

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

答案 1 :(得分: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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分: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;

fiddle

答案 4 :(得分: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