简体   繁体   English

mysql查询中的两个联接未返回预期结果

[英]Two joins in mysql query not returning expected result

I am working on a join and I cannot seem to get the resultset that I need. 我正在进行联接,但似乎无法获得所需的结果集。 Let me paint the scenario: 让我描绘一下场景:

I have 2 tables: 我有2张桌子:

Data table 数据表

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

Join table 联接表

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

Expected Result Set 预期结果集

+---------------+-----------------+---------------+----------------+----------------+
| 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            |
+---------------+-----------------+---------------+----------------+----------------+

My Query 我的查询

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

What is happening is that the join on table C is being done on the resultset of the join between table A and B, therefore the resultset is blank. 发生的情况是,表C和表B之间的联接结果集正在执行表C上的联接,因此结果集为空白。

I want the join on table C to be applied on table A and not on the resultset from the join between table A and B; 我希望将表C上的联接应用于表A,而不是表A和B之间的联接的结果集; which will result on the expected resultset. 这将产生预期的结果集。

Can anyone help? 有人可以帮忙吗?

Thanks 谢谢

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

This will return you: 这将返回您:

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

Now, it seems you want to filter out: 现在,看来您想过滤掉:

10  Test1   10  3       abc

and keep 并保持

10  Test1   10      1   def

Is that what you want? 那是你要的吗?

Regards 问候

The expression C.FID <> null will never evaluate to true, it will always return NULL. 表达式C.FID <> null将永远不会为true,它将始终返回NULL。 An inequality comparison to NULL will always evaluate to NULL . NULL的不相等比较将始终得出NULL (In SQL, in a boolean context, en expression will evaluate to one of three possible values: TRUE , FALSE or NULL .) (在SQL中,在布尔上下文中,en表达式将求值为三个可能值之一: TRUEFALSENULL 。)

If you want a comparison to NULL to return TRUE or FALSE , use an IS [NOT] NULL comparison test. 如果要与NULL进行比较以返回TRUEFALSE ,请使用IS [NOT] NULL比较测试。 An expression like 像这样的表达

foo IS NULL

or 要么

foo IS NOT NULL

Or, you could make use the MySQL specific null-safe comparison (spaceship) operator: 或者,您可以使用MySQL特定的null安全比较(spaceship)运算符:

foo <=> NULL

or 要么

NOT (foo <=> NULL)

As to the result you want to return, it's a bit confusing as to how you arrive at what you want to return. 至于您要返回的结果,就如何到达要返回的内容有些困惑。

To me, it looks like you are wanting to get the matching rows from jointable ... if there are matching rows with fid=3 , return just those rows. 对我来说,您似乎想从jointable获取匹配的行...如果有匹配的行具有fid=3 ,则仅返回这些行。 If there aren't any matching rows with fid=3 , then return rows that have a NULL value in fid and gid=1 . 如果没有任何匹配的行具有fid=3 ,则返回在fidgid=1中具有NULL值的行。

If that's what we want returned, we can write a query that does that. 如果那是我们想要返回的内容,我们可以编写一个查询来完成。 If that's not what we want returned, then the rest of this answer doesn't matter. 如果这不是我们想要返回的内容,那么其余答案都无关紧要。

We can use a NOT EXISTS predicate to test for the non existence of matching rows. 我们可以使用NOT EXISTS谓词来测试不存在匹配行。

For example: 例如:

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
                        )
       )

To be honest not sure if I understand what you want, so this might not be correct. 老实说,不确定我是否了解您的要求,因此这可能是不正确的。 What I think you want is. 我想你想要的是。 You have two tables and want to join all rows from the join table where the id matches and fid= 3 or gid=1 and fid not null. 您有两个表,并且希望连接ID匹配且fid = 3或gid = 1且fid不为null的联接表中的所有行。 The query for this should be something like this. 查询应该是这样的。 (one join should be enough) (一次加入就足够了)

Select
   *
from
   datatable A
join jointable b
on
   A.ID = B.ID
where b.fid = 3 or (b.gid = 1 and b.fid <> null)
SELECT *
FROM   table1 a
INNER JOIN table2 b ON a.ID = b.ID
WHERE b.FID = 3 OR b.GID = 1

But your question is not very specific as far as the WHERE clauses 但是就WHERE子句而言,您的问题不是很具体

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

Why do you use C.FID <> null when B.GID = 1? 当B.GID = 1时为什么使用C.FID <> null? It should be null. 它应该为空。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM