具有多列且可能返回 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;
我有几个 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;