在我的INNER JOIN中使用OR子句

时间:2015-10-08 17:41:34

标签: mysql sql

我有以下两个表,

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 loginsuser_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 _一个_?

5 个答案:

答案 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