具有多列且可能返回 null 的子查询 (SQL)

Subquery with multiple columns and possible null returned (SQL)

我有几个 table 需要从中提取信息,但我觉得我这样做的方式可以优化。 上下文是一个玩家向另一个玩家提供信息。这些信息是游戏的传说元素,因此已经在 table“knlist”中定义。谁提供了什么信息存储在 table“knlogs”中。

所以当一个玩家要给另一个玩家一个信息的时候,首先要看这个玩家是否已经有。所以我想要的是这个玩家所有知识的列表,还有额外的列说明是否已经有其他玩家拥有它的日志。 这对于子查询来说已经足够简单了,但是在我需要来自这个可能的日志的另一个信息之后,子查询中的第二列。在这里,我不能加入 tables,因为日志完全有可能根本不存在。我需要在列中返回一个空值。

这是我现在的制作方法。问题是我有两个子查询访问完全相同的行(如果存在的话)。

表格: 请注意,每一个都有更多的列,但是为了简单起见...

knlist                                | knlogs
                                      |
idknowledge        description        | idknowledge        idlearner          dateknowledge      datetheory
----------------   ----------------   | ----------------   ----------------   ----------------   ----------------
1                  Some text.         | 1                  6166               2020-08-07         0000-00-00
2                  Some more text.    | 2                  6166               2020-08-07         0000-00-00
3                  Sample data.       | 1                  3069               2020-08-01         0000-00-00
4                  Even more text.    | 3                  3069               0000-00-00         2019-12-31

假设用户 6166 想向用户 3069 提供一些信息。我想看看 3069 是否已经拥有这些信息,或者是否有相关理论。

SELECT li.description, li.idknowledge,
  (SELECT datetheory FROM knlogs where idknowledge=li.idknowledge and idlearner=3092) as datetheory_user_2,
  (SELECT dateknowledge FROM knlogs where idknowledge=li.idknowledge and idlearner=3092) AS dateknowledge_user_2
FROM knlist as li, knlogs as lo
WHERE li.idknowledge=lo.idknowledge and lo.idlearner=6166

这就是我所拥有的,并且有效。它 returns :

description        idknowledge        datetheory_user_2         dateknowledge_user_2
----------------   ----------------   -----------------------   -----------------------
Some text.         1                  0000-00-00                2020-08-01                
Some more text.    2                  NULL                      NULL

现在请求包含相同的子查询,只是在两个不同的列上。我想我不能加入 FROM 部分中选择的另一个 table,因为可能为 NULL。如果我这样做,我会跳过返回的第二行。

有人对此有好的替代方案吗?谢谢。

从不FROM 子句中使用逗号。 始终使用正确、明确、标准、可读的JOIN语法。

如果您想避免子查询,只需使用 left join:

SELECT li.description, li.idknowledge,
       lo2.datetheory as datetheory_user_2,
       lo2.dateknowledge as dateknowledge_user_2
FROM knlist li join
     knlogs lo
     on li.idknowledge = lo.idknowledge left join
     knlogs lo2
     on lo2.idknowledge = lo.idknowledge and
        lo2.idlearner = 3092
WHERE lo.idlearner = 6166;