我有以下两个表,
CREATE TABLE logins (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
user_id_1 INT NOT NULL,
user_id_2 INT DEFAULT 0,
user_id_3 INT DEFAULT 0,
PRIMARY KEY (id)
) ENGINE=MyISAM;
CREATE TABLE user_data (
user_id NOT NULL,
day DATE NOT NULL,
PRIMARY KEY (`user_id, `day`)
) ENGINE=MyISAM;
此架构可以使用重构,但我已经继承了它,现在必须编写一个JOIN
logins
和user_data
的查询。我需要选择user_data
中> 0
个值为user_id_?
之一的所有行。
我不完全确定如何编译此查询,正在考虑以下方面:
SELECT logins.user_id_1, logins.user_id_2, logins.user_id_3, user_data.day,
FROM logins
INNER JOIN user_data
ON (logins.user_id_1 = user_data.user_id OR ??)
查询此问题的最佳方式是哪种情况,我将检索最多3行,每个user_id _一个_?
答案 0 :(得分:2)
允许使用OR。另一种选择是将join连接到user_data表三次,并检查是否有任何一个返回。您可能想要尝试两者,看看哪个表现更好。我的猜测是它们大致相同,但我对MySQL计划生成器并不熟悉。
SELECT
l.user_id_1
,l.user_id_2
,l.user_id_3
--consider: what if there is a match in more
--than one table? what do you want to happen?
,case when ud1.day is not null then ud1.day
when ud2.day is not null then ud2.day
when ud3.day is not null then ud3.day
else null
end as day
FROM
logins l
left JOIN user_data ud1 on ud1.user_id = l.user_id_1
left join user_data ud2 on ud2.user_id = l.user_id_2
left join user_data ud3 on ud3.user_id = l.user_id_3
where ud1.user_id is not null
or ud2.user_id is not null
or ud3.user_id is not null
答案 1 :(得分:0)
你可以使用或。
SELECT logins.user_id_1, logins.user_id_2, logins.user_id_3, user_data.day,
FROM logins
INNER JOIN user_data
ON logins.user_id_1 = user_data.user_id OR
logins.user_id_2 = user_data.user_id OR
logins.user_id_3 = user_data.user_id
此语法可用于选择与一个或其他条件匹配的所有记录。
答案 2 :(得分:0)
当ON
完全没有OR AND和其他布尔操作的限制时,你可以设置不同条件的任意组合,与WHERE
子句相同
SELECT logins.user_id_1, logins.user_id_2, logins.user_id_3, user_data.day,
FROM logins
INNER JOIN user_data
ON logins.user_id_1 = user_data.user_id OR
logins.user_id_2 = user_data.user_id OR
logins.user_id_3 = user_data.user_id
或者您可能不需要logins.user_id_1, logins.user_id_2, logins.user_id_3
,只需要user_data.user_id
:
SELECT user_data.user_id, user_data.day,
FROM logins
INNER JOIN user_data
ON logins.user_id_1 = user_data.user_id OR
logins.user_id_2 = user_data.user_id OR
logins.user_id_3 = user_data.user_id
答案 3 :(得分:0)
你可以试试这个:
SELECT logins.user_id_1, logins.user_id_2, logins.user_id_3, user_data.day,
FROM logins,user_data
WHERE user_data.user_id in (logins.user_id_1,logins.user_id_2,logins.user_id_3)
答案 4 :(得分:0)
你可以使用UNION
,这会在每个登录行返回多行,不知道你是否需要这个:
SELECT l.user_id, user_data.*
FROM user_data as u
INNER JOIN
(
select user_id_1 --, could add other columns...
from logins
union
select user_id_2 --, could add other columns...
from logins
where user_id_2 > 0
union
select user_id_3 --, could add other columns...
from logins
where user_id_3 > 0
) as l
ON l.user_id = user_data.user_id