mysql查询中的两个连接没有返回预期的结果

时间:2016-03-15 13:41:21

标签: mysql sql join resultset

我正在进行连接,但我似乎无法获得所需的结果集。让我描绘一下情景:

我有两张桌子:

数据表

+----+-------+
| ID | Name  |
+----+-------+
| 10 | Test1 |
| 11 | Test2 |
| 12 | Test3 |
| 13 | Test4 |
| 14 | Test5 |
| 15 | Test6 |
+----+-------+

加入表

+----+-----+-----+-----+
| ID | FID | GID | Val |
+----+-----+-----+-----+
| 10 |   3 |     | abc |
| 10 |     |   1 | def |
| 11 |   3 |     | ijk |
| 12 |     |   1 | lmn |
| 13 |   4 |     | opq |
+----+-----+-----+-----+

预期结果集

+---------------+-----------------+---------------+----------------+----------------+
| Data table id | Data table name | Join Tabe FID | Join Table GID | Join Table Val |
+---------------+-----------------+---------------+----------------+----------------+
|            10 | Test1           |             3 |                | abc            |
|            11 | test2           |             3 |                | ijk            |
|            12 | test3           |               |              1 | lmn            |
+---------------+-----------------+---------------+----------------+----------------+

我的查询

Select
   *
from
   datatable A
join jointable b
on
   A.ID = B.ID
   and B.FID = 3
join jointable c
on
   A.ID = C.ID
   and C.GID = 1
   and C.FID <> null

正在发生的是表C上的连接是在表A和B之间的连接的结果集上完成的,因此结果集是空白的。

我希望表C上的连接应用于表A,而不是表A和B之间的连接的结果集;这将产生预期的结果集。

有人可以帮忙吗?

由于

5 个答案:

答案 0 :(得分:1)

SELECT
*
FROM datatable A
LEFT JOIN jointable B ON A.ID = B.ID 
WHERE B.FID = 3 OR B.GID = 1;

这会让你回复:

10  Test1   10  3       abc
10  Test1   10      1   def
11  Test2   11  3       ijk
12  Test3   12      1   lmn

现在,您似乎想要过滤掉:

10  Test1   10  3       abc

并保持

10  Test1   10      1   def

这就是你想要的吗?

此致

答案 1 :(得分:1)

表达式 C.FID <> null 永远不会评估为true,它将始终返回NULL。与NULL的不等式比较将始终评估为NULL。 (在SQL中,在布尔上下文中,en表达式将计算为三个可能值之一:TRUEFALSENULL。)

如果您希望与NULL进行比较以返回TRUEFALSE,请使用IS [NOT] NULL比较测试。像

这样的表达式
foo IS NULL

foo IS NOT NULL

或者,您可以使用MySQL特定的零安全比较(太空船)运算符:

foo <=> NULL

NOT (foo <=> NULL)

至于你想要归还的结果,对你如何达到想要归来的东西感到有些困惑。

对我而言,看起来您希望从jointable获取匹配的行...如果匹配的行包含fid=3,则只返回这些行。如果没有与fid=3匹配的任何行,则返回fidgid=1中具有NULL值的行。

如果我们想要返回的内容,我们可以编写一个查询来执行该操作。如果那不是我们想要的,那么这个答案的其余部分并不重要。

我们可以使用NOT EXISTS谓词来测试是否存在匹配的行。

例如:

SELECT d.id 
     , d.name
     , j.fid
     , j.gid
     , j.val
  FROM datatable d
  JOIN jointable j
    ON j.id = d.id
 WHERE ( j.fid = 3 )
    OR ( j.fid IS NULL
         AND j.gid = 1 
         AND NOT EXISTS ( SELECT 1
                            FROM jointable t
                           WHERE t.id = d.id
                             AND t.fid = 3
                        )
       )

答案 2 :(得分:0)

说实话,不确定我是否理解你想要的东西,所以这可能不正确。我认为你想要的是。 你有两个表,想要加入id匹配的连接表中的所有行,fid = 3或gid = 1,fid不为null。对此的查询应该是这样的。 (一个连接就足够了)

Select
   *
from
   datatable A
join jointable b
on
   A.ID = B.ID
where b.fid = 3 or (b.gid = 1 and b.fid <> null)

答案 3 :(得分:0)

SELECT *
FROM   table1 a
INNER JOIN table2 b ON a.ID = b.ID
WHERE b.FID = 3 OR b.GID = 1

但就WHERE条款

而言,你的问题并不是非常具体

答案 4 :(得分:0)

SELECT * FROM db1 
INNER JOIN db2 ON db1.id = db2.id
WHERE db1.FID = 3 or db2.GID = 1;

为什么使用C.FID&lt;&gt;当B.GID = 1时为null?它应该为空。