我想要一个查询从两个不同的表中获取结果,其中特定用户已添加该行。所以我的2个表看起来像这样:
所以,我想从user_id行等于1的两个表中提取内容。对于上下文,假设每个用户可以向网站添加多个地址和电子邮件,我想抓住它们以显示在他们的个人资料页面上。
所以我尝试了这个:
SELECT *
FROM addresses
JOIN emails USING (user_id)
WHERE user_id = '1'
但是这不起作用 - 它从第一个表中返回每行2个,或者根本不返回任何内容。 我也试过这个:
SELECT *
FROM addresses,
emails
WHERE user_id = '1'
但这也没有任何回报。
答案 0 :(得分:1)
SELECT table1.*,table2.*
FROM table1 INNER JOIN
table2 ON table1.user_ID = table2.user_id
Where table1.user_id = 1
来自输入
table1: table2
id user_id address id user_id email
---------------------- ----------------------
1 1 Add1 1 1 Email1
2 1 Add2 2 1 Email2
3 2 Add3 3 2 Email3
4 2 Add4 4 3 Email4
预期产出
id user_id address id user_id email
----------------------------------------------
1 1 Add1 1 1 Email1
2 1 Add2 1 1 Email1
1 1 Add1 2 1 Email2
2 1 Add2 2 1 Email2
答案 1 :(得分:1)
以下是使用笛卡尔积的查询
SELECT A.*,B.* FROM
(SELECT address FROM addresses WHERE user_id = 1) A,
(SELECT email FROM emails WHERE user_id = 1) B;
以下是使用INNER JOIN的查询
SELECT A.*,B.* FROM
(SELECT address FROM addresses WHERE user_id = 1) A
INNER JOIN
(SELECT email FROM emails WHERE user_id = 1) B
USING (user_id);
这两个查询都被重构为每个查询一行。在搜索user_id 1之前,无需将整个数据集放在一起。
有一点需要注意:请在两个表中对用户user_id编制索引:
ALTER TABLE addresses ADD INDEX (user_id);
ALTER TABLE emails ADD INDEX (user_id);
以下是其他内容:如果user_id 1有多个地址和/或多个电子邮件,那么这两个查询应该是这样的:
多个地址/多个电子邮件的笛卡尔积
SELECT A.*,B.* FROM
(SELECT GROUP_CONCAT(address) AddressList FROM addresses WHERE user_id = 1) A,
(SELECT GROUP_CONCAT(email) EmailList FROM emails WHERE user_id = 1) B;
多个地址/多个电子邮件的内部联接
SELECT A.*,B.* FROM
(SELECT GROUP_CONCAT(address) AddressList FROM addresses WHERE user_id = 1) A
INNER JOIN
(SELECT GROUP_CONCAT(email) EmailList FROM emails WHERE user_id = 1) B
USING (user_id);
试一试!!!
更新2011-08-29 11:52美国东部时间
由于无法保证user_id同时具有地址和电子邮件地址。你必须执行LEFT JOIN而不是INNER JOIN,因为LEFT JOIN必须支持至少其中一个现有的entners而不是INNER JOIN,迫使一个拥有两个实体的user_id。尝试其中之一:
SELECT
A.ListOfAddresses AddressList,
IFNULL(B.ListOfEmails,'<No Email Address>') EmailList
FROM
(SELECT GROUP_CONCAT(address) ListOfAddresses FROM addresses WHERE user_id = 1) A
LEFT JOIN
(SELECT GROUP_CONCAT(email) ListOfEmails FROM emails WHERE user_id = 1) B
USING (user_id);
或
SELECT
IFNULL(B.ListOfAddresses,'<No Address>') AddressList,
A.ListOfEmails EmailList
FROM
(SELECT GROUP_CONCAT(email) ListOfEmails FROM emails WHERE user_id = 1) A
LEFT JOIN
(SELECT GROUP_CONCAT(address) ListOfAddresses FROM addresses WHERE user_id = 1) B
USING (user_id);
答案 2 :(得分:0)
尝试
"SELECT * FROM table1 INNER JOIN table2 USING (user_id) WHERE user_id = '1'"
然后尝试这个
SELECT address.table1 , email.table2 FROM table1 INNER JOIN table2 ON id.table1 ='1'
答案 3 :(得分:0)
根据问题下面的评论,问题实际上似乎是基于通用标准对不同表格中的行进行排序。
除了具有单独的SELECT并执行排序客户端之外,数据库服务器还可以为您执行排序,大致如下所示:
SELECT *
FROM (
SELECT
id addresses_id,
address address_addresses,
NULL emails_id,
NULL emails_email,
time
FROM
addresses
WHERE
user_id = 1
UNION ALL
SELECT
NULL addresses_id,
NULL address_addresses,
id emails_id,
email emails_email,
time
FROM
emails
WHERE
user_id = 1
)
ORDER BY
time -- Column not mentioned in question.
注意:有些返回的行最后会有NULL(这些来自addresses
表),有些则位于前面(这些来自emails
)。
这个UNION相当丑陋,但每张新桌子都会变得更加丑陋......
答案 4 :(得分:0)
简单联盟版本:
Select user_id, address as details from addresses
where user_ID = 1
UNION
Select user_id, email as details from emails
where user_ID = 1
以下是关于联盟的一些快速阅读: http://www.tizag.com/sqlTutorial/sqlunion.php
来自输入
table1: table2
id user_id address id user_id email
---------------------- ----------------------
1 1 Add1 1 1 Email1
2 1 Add2 2 1 Email2
3 2 Add3 3 2 Email3
4 2 Add4 4 3 Email4
结果将是
user_id details
-----------------------
1 Add1
1 Add2
1 Email1
1 Email2