问题描述
我有一些表需要从中提取信息,但是我觉得可以优化这种方式。 上下文是一个玩家向另一个玩家提供信息。这些信息是游戏的知识元素,因此已经在表“ knlist”中定义。谁提供的信息存储在“ knlogs”表中。
因此,当一个玩家想要将信息提供给另一位玩家时,它首先需要查看该玩家是否已经拥有该信息。因此,我想要的是该球员的全部知识的清单,另外的列表示是否已有其他球员拥有的日志。 用子查询就足够简单了,但是在我需要这个可能的日志中的另一个信息之后,所以子查询中的第二列。在这里,我无法加入表,因为完全有可能日志根本不存在。我需要在列中返回空值。
这是我现在做这个的方式。问题是我有两个子查询可以访问完全相同的行(如果存在)。
表格: 请注意,每列中都有更多列,但为简单起见...
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
现在,请求仅在两个不同的列上包含相同的子查询。我认为由于可能为NULL,所以我无法与FROM部分中选择的另一个表联接。如果要这样做,我将跳过返回的第二行。
有人能替代这个吗?谢谢。
解决方法
从不在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;