【发布时间】:2015-03-23 08:01:25
【问题描述】:
更新 1
我发现它什么时候做错了。如果视图由两个表组成,则只有第一个表中的字段在子查询中具有值。我不知道为什么,但是如果我更改 JOIN 顺序,它会起作用。一旦我尝试将另一个字段与第二个表匹配,它就会再次返回 NULL。
更新 2
我在这里创建了一个工作示例:http://sqlfiddle.com/#!2/d4eb97/1
更新 3
相同的示例适用于较新的 MySQL 版本 (5.6.6),因此 5.5 中可能存在错误 - http://sqlfiddle.com/#!9/4e140/2
我有一个架构,我在其中结束了这样的 SQL:
SELECT view.user,
(
SELECT tableA.user
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.tableA_id
WHERE tableA.user = view.user
LIMIT 1
) as b_user
FROM view
WHERE view.user = 1
我在这里做的很简单:
- 从
view中选择两个字段view是 MySQL 视图,而不是真实表。 - 第二个字段是一个子查询:
2.1 表的字段用户tableA
2.2 与表tableB与关系字段的左连接tableB中还没有行
2.3 仅当tableA用户与view中的用户相同
2.4 限制1,仅用于本例 - 将结果限制为
user = 1
这里奇怪的是,在某些情况下b_user这个字段是NULL,但是数据是ok的。
我可以进行三个更改以使其正常工作:
修复 1
手动输入用户ID使其工作
SELECT view.user,
(
SELECT tableA.user
FROM tableA
LEFT JOIN tableB ON tableA.id = tableB.tableA_id
WHERE tableA.user = 1
LIMIT 1
) as b_user
FROM view
WHERE view.user = 1
修复 2
删除左连接也使其工作:
SELECT view.user,
(
SELECT tableA.user
FROM tableA
WHERE tableA.user = view.user
LIMIT 1
) as b_user
FROM view
WHERE view.user = 1
修复 3
另一种选择是不使用 MySQL 视图:
SELECT view.user,
(
SELECT tableA.user
FROM tableA
WHERE tableA.user = view_table_a.user
LEFT JOIN tableB ON tableA.id = tableB.tableA_id
LIMIT 1
) as b_user
FROM view_table_a INNER JOIN view_table_b ON condition
WHERE table_a.user = 1
我无法手动重现此重新创建新数据库架构,它仅发生在我当前的设置中,由于安全原因,我无法在此处公开。
为什么子查询返回 NULL 值?我需要使第一个查询工作,因为我无法使用这三个修复中的任何一个。
【问题讨论】:
-
您有问题吗?
-
我认为这是含蓄的,抱歉。为什么子查询返回 NULL 值?
-
如果您愿意,请考虑遵循以下简单的两步操作: 1. 如果您还没有这样做,请提供适当的 DDL(和/或 sqlfiddle),以便我们可以更轻松地复制问题。 2. 如果您尚未这样做,请提供与步骤 1 中提供的信息相对应的所需结果集。
-
我什至无法自己复制这个问题,我决定问一下,以防有人对此有任何想法......我仍在寻找,如果我能重现它,我将发布所有 SQL所以你可以正确地测试它。
-
我取得了一些进展,这个问题有一个 sqlfiddle:sqlfiddle.com/#!2/d4eb97/1
标签: mysql sql subquery views left-join