MySQL 视图、子查询和左连接的组合产生了一个奇怪的结果

MySQL combination of view, subquery and left join produces a strange result

更新 1

我发现它什么时候做错了。如果视图由两个 table 组成,则只有第一个 table 中的字段在子查询中具有值。我不知道为什么,但如果我更改 JOIN 顺序,它就会起作用。一旦我尝试将另一个字段与第二个 table 匹配,它再次 returns 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

我在这里做的很简单:

  1. Select 来自 view
    的两个字段 view 是 MySQL 视图,不是真实的 table。
  2. 第二个字段是以下的子查询:
    2.1 tabletableA
    的现场用户 2.2 Left join with table tableB with the relational field
    tableB 中还没有行
    2.3 仅当 tableA 用户与 view
    中的用户相同时 2.4 极限1,仅针对本例
  3. 将结果限制为 user = 1

这里比较奇怪的是有些情况下字段b_userNULL,但是数据没问题

我可以进行三处更改以使其有效:

修复 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

我无法通过手动重新创建一个新的数据库模式来重现这个,它只发生在我当前的设置中,出于安全原因我不能在这里公开。

为什么子查询 return NULL 值? 我需要使第一个查询工作,因为我不能使用三个修复中的任何一个。

为什么首先要有子查询?我喜欢子查询,它们是非常方便的东西。但如果没有必要,则不应使用它们。如果没有我们的帮助,查询会变得非常复杂。

您正在寻找主 table 中的特定用户(它实际上是一个视图的事实是无关紧要的)然后使用相同的用户值与 TableA 连接,然后可选择使用与该用户关联的 ID 值:

select  rs.Origin, a.Origin as Same_Origin
from    requests_status  rs
join    assignments      a
    on  a.employee = rs.employee
    and a.origin   = rs.origin
left join assignments_author aa
    on  aa.assignment = a.id
where   rs.employee = 1;

然后我注意到在您的小提琴中,您创建了 assignments_author table 但从未填充它。但这并不重要,因为你离开了加入它。但是您不使用来自 table 的任何数据。所以实际上,您根本不需要 table 在您的查询中。因此等效查询将是:

select  rs.Origin, a.Origin as Same_Origin
from    requests_status  rs
join    assignments      a
    on  a.employee = rs.employee
    and a.origin   = rs.origin
where   rs.employee = 1;

我不知道你为什么在一个中得到 NULL 而在另一个中却没有。但是由于上面的查询 returns 在两个小提琴中都有相同的答案并且是预期的结果,所以我在这里的工作完成了。

我认为这是一个错误,也许是这个 (http://bugs.mysql.com/bug.php?id=52051) because the query fails in MySQL 5.5 (http://sqlfiddle.com/#!2/d4eb97/1) but works in 5.6 (http://sqlfiddle.com/#!9/4e140/2)