2016-03-15 99 views
0

我正在进行连接,我似乎无法获得我需要的结果集。让我画的情景:在mysql查询中的两个连接没有返回预期的结果

我有2个表:

数据表

+----+-------+ 
| 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之间连接的结果集;这将导致预期的结果集。

任何人都可以帮忙吗?

感谢

+1

有与3的'id'没有记录,所以我希望'B.ID = 3'过滤掉所有的记录。 –

+0

我认为你需要的是一个左外连接,但是我没有完全理解你的问题。 –

+0

@GordonLinoff对不起,是一个错字,纠正 – Yash

回答

1

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

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

foo <=> NULL 

NOT (foo <=> NULL) 
:像

foo IS NULL 

foo IS NOT NULL 

或者,你可以使用MySQL的特定空安全的比较(飞船)运算符的表达式


至于你想要返回的结果,对于你如何到达你想要返回的结果有点困惑。

对我来说,它看起来像你想从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 
         ) 
     ) 
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) 
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 

这就是你想要的吗?

问候

+2

这里的左连接是不必要的,WHERE B使它成为INNER JOIN – Mihai

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

不过你的问题不是很具体尽可能的WHERE子句

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

为什么使用C.FID <>空当B.GID = 1?它应该是空的。