1

我有两个表,如此处所示

我正在尝试获取nameregister变量 WHENregister变量不存在值。

使用下面的查询我得到的结果显示在这里

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id
WHERE (t1.register = 'absent' OR t1.register is null)

当我使用下面的查询时,我得到 INCORRECT 结果,如下所示

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)

我的问题是:为什么在上述情况下我得到不同的结果。我在 ON 子句本身中使用 WHERE 条件,因此我不需要编写 WHERE 条件。

有人可以指出我正确的方向吗?

4

3 回答 3

3

如果将"t1.register = 'absent' OR t1.register is null"条件放在 WHERE 子句中,它将在联接之后应用,而如果将其放在 ON 子句中,则会影响联接。

这是绝对正常和理想的行为:)

在这里你必须把它放在 WHERE 子句中:)

于 2012-06-16T12:37:36.943 回答
1

我通常不会使用右连接,而是使用左连接......我知道它们实际上是相同的,只是你想要记录的连接中的哪个表。正如 Olivier 提到的,WHERE 子句在连接条件之后应用。我通常会先问我想要什么......在你的情况下,我希望所有用户都列出,而不管注册时间......所以,我简单地把它说成

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id

我的左表(总是想要的)是用户......时间是右表,我总是试图保持我的“ON”连接条件代表左/右相关性以提高可读性。

现在,这不是您想要的,而是我开始的地方……现在,如何应用“缺席”状态。由于上面已经获得了所有用户,并且您只想查看出现“缺席”的条目,请将其添加到 JOIN 部分,因为这些是您有兴趣查看的唯一条目。

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id
          AND t.register = 'absent'

所以,只有“缺席”的记录才会显示他们各自的寄存器和 mydate 值......任何其他记录,你仍然会得到每个人。不需要 WHERE 子句。

但是,如果说您只想要特定类型或状态的用户,您可以添加它以限制您想要查看的那些“用户”......例如

select
      u.Name,
      t.register,
      t.myDate
   from
      users u
         LEFT JOIN time t
            on u.user_id = t.user_id
          AND t.register = 'absent'
   where
      u.SomeStatus = whatever
于 2012-06-16T13:09:16.797 回答
0

您的问题与查询的执行顺序有关。正常顺序是

 From
 JOIN
 WHERE
 SELECT

所以,在第一个例子中

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id
WHERE (t1.register = 'absent' OR t1.register is null)

首先,两个表将根据条件连接在一起(使用内连接)t2.user_id=t1.user_id,然后将时间表中所有不匹配的行添加到临时结果表中。最后,将 WHERE 子句(t1.register = 'absent' OR t1.register is null)中的条件应用于临时表以产生最终结果。

在第二个例子中

SELECT t2.name, t1.register, t1.mydate 
FROM time t1
RIGHT JOIN user t2
ON t2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)

首先,两个表根据条件连接在一起(使用内连接)t2.user_id=t1.user_id AND (t1.register = 'absent' OR t1.register is null)接下来,将time中所有不匹配的行添加到结果中。

尽管如此,这两个查询的结果是不同的。

如果您使用INNER JOIN,那么 WHERE 或 ON 子句的条件会产生相同的结果。仅当您使用OUTER JOIN (LEFT/RIGHT/CROSS)时,它们才会有所不同。

于 2012-06-16T13:06:22.743 回答