mysql 查询中的两个连接未返回预期结果
Two joins in mysql query not returning expected result
我正在进行联接,但似乎无法获得所需的结果集。让我描绘场景:
我有 2 个 tables:
数据table
+----+-------+
| ID | Name |
+----+-------+
| 10 | Test1 |
| 11 | Test2 |
| 12 | Test3 |
| 13 | Test4 |
| 14 | Test5 |
| 15 | Test6 |
+----+-------+
加入table
+----+-----+-----+-----+
| 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
发生的事情是 table C 上的连接是在 table A 和 B 之间连接的结果集上完成的,因此结果集是空白的。
我希望 table C 上的连接应用于 table A 而不是 table A 和 B 之间连接的结果集;这将产生预期的结果集。
有人能帮忙吗?
谢谢
老实说我不确定我是否理解你想要的,所以这可能不正确。我想你想要的是。
您有两个 table 并且想要连接来自连接 table 的所有行,其中 id 匹配且 fid= 3 或 gid=1 且 fid 不为空。对此的查询应该是这样的。 (一个连接就够了)
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 datatable A
LEFT JOIN jointable B ON A.ID = B.ID
WHERE B.FID = 3 OR B.GID = 1;
这将 return 你:
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
这是你想要的吗?
此致
SELECT *
FROM table1 a
INNER JOIN table2 b ON a.ID = b.ID
WHERE b.FID = 3 OR b.GID = 1
但就 WHERE 子句而言,你的问题不是很具体
SELECT * FROM db1
INNER JOIN db2 ON db1.id = db2.id
WHERE db1.FID = 3 or db2.GID = 1;
为什么在 B.GID = 1 时使用 C.FID <> null?它应该是空的。
表达式 C.FID <> null
永远不会计算为真,它总是 return NULL。与 NULL
的不等式比较将始终计算为 NULL
。 (在 SQL 中,在布尔上下文中,en 表达式将计算为 三个 可能值之一:TRUE
、FALSE
或 NULL
.)
如果您想将 NULL
与 return TRUE
或 FALSE
进行比较,请使用 IS [NOT] NULL
比较测试。像
这样的表达式
foo IS NULL
或
foo IS NOT NULL
或者,您可以使用 MySQL 特定的空安全比较(宇宙飞船)运算符:
foo <=> NULL
或
NOT (foo <=> NULL)
至于你想要的结果 return,关于你如何达到你想要的结果有点令人困惑 return。
对我来说,您似乎想从 jointable
中获取匹配的行...如果有 fid=3
的匹配行,return 就是这些行。如果没有任何与 fid=3
匹配的行,则 return 行在 fid
和 gid=1
.
中具有 NULL 值
如果这就是我们想要的 returned,我们可以编写一个查询来执行此操作。如果那不是我们想要的 returned,那么这个答案的其余部分并不重要。
我们可以使用 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 个 tables:
数据table
+----+-------+
| ID | Name |
+----+-------+
| 10 | Test1 |
| 11 | Test2 |
| 12 | Test3 |
| 13 | Test4 |
| 14 | Test5 |
| 15 | Test6 |
+----+-------+
加入table
+----+-----+-----+-----+
| 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
发生的事情是 table C 上的连接是在 table A 和 B 之间连接的结果集上完成的,因此结果集是空白的。
我希望 table C 上的连接应用于 table A 而不是 table A 和 B 之间连接的结果集;这将产生预期的结果集。
有人能帮忙吗?
谢谢
老实说我不确定我是否理解你想要的,所以这可能不正确。我想你想要的是。 您有两个 table 并且想要连接来自连接 table 的所有行,其中 id 匹配且 fid= 3 或 gid=1 且 fid 不为空。对此的查询应该是这样的。 (一个连接就够了)
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 datatable A
LEFT JOIN jointable B ON A.ID = B.ID
WHERE B.FID = 3 OR B.GID = 1;
这将 return 你:
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
这是你想要的吗?
此致
SELECT *
FROM table1 a
INNER JOIN table2 b ON a.ID = b.ID
WHERE b.FID = 3 OR b.GID = 1
但就 WHERE 子句而言,你的问题不是很具体
SELECT * FROM db1
INNER JOIN db2 ON db1.id = db2.id
WHERE db1.FID = 3 or db2.GID = 1;
为什么在 B.GID = 1 时使用 C.FID <> null?它应该是空的。
表达式 C.FID <> null
永远不会计算为真,它总是 return NULL。与 NULL
的不等式比较将始终计算为 NULL
。 (在 SQL 中,在布尔上下文中,en 表达式将计算为 三个 可能值之一:TRUE
、FALSE
或 NULL
.)
如果您想将 NULL
与 return TRUE
或 FALSE
进行比较,请使用 IS [NOT] NULL
比较测试。像
foo IS NULL
或
foo IS NOT NULL
或者,您可以使用 MySQL 特定的空安全比较(宇宙飞船)运算符:
foo <=> NULL
或
NOT (foo <=> NULL)
至于你想要的结果 return,关于你如何达到你想要的结果有点令人困惑 return。
对我来说,您似乎想从 jointable
中获取匹配的行...如果有 fid=3
的匹配行,return 就是这些行。如果没有任何与 fid=3
匹配的行,则 return 行在 fid
和 gid=1
.
如果这就是我们想要的 returned,我们可以编写一个查询来执行此操作。如果那不是我们想要的 returned,那么这个答案的其余部分并不重要。
我们可以使用 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
)
)