我有一些表需要从中提取信息,但我觉得我这样做的方式可以优化。上下文是一个玩家向另一个玩家提供信息。这些信息是游戏的传说元素,因此已经在表"中定义;knlist";。谁给出了存储在表中的什么信息;knlogs";。
因此,当一名玩家想向另一名玩家提供信息时,首先需要查看该玩家是否已经拥有该信息。因此,我想要的是该玩家所有知识的列表,并添加其他列,说明是否已经有其他玩家拥有该信息的日志。对于子查询来说,这就足够简单了,但紧接着我需要这个可能的日志中的另一个信息,所以需要子查询中的第二列。在这里,我不能加入表,因为日志完全有可能根本不存在。我需要在列中返回一个null。
以下是我目前的制作方法。问题是,我有两个子查询访问完全相同的行(如果存在的话(。
表:请注意,每个表中都有更多的列,但为了简单起见。。。
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
这就是我所拥有的,它是有效的。它返回:
description idknowledge datetheory_user_2 dateknowledge_user_2
---------------- ---------------- ----------------------- -----------------------
Some text. 1 0000-00-00 2020-08-01
Some more text. 2 NULL NULL
现在,请求包含相同的子查询,只是在两个不同的列上。我想我不能加入FROM部分中选择的另一个表,因为可能存在NULL。如果我要这样做,我会跳过返回的第二行。
有人能替代这个吗?非常感谢。
Never在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;