【问题标题】:Why does LEFT JOIN work in this query with rowid but INNER JOIN does not?为什么 LEFT JOIN 在这个带有 rowid 的查询中起作用,而 INNER JOIN 却不起作用?
【发布时间】:2019-09-30 14:37:03
【问题描述】:

我有一个简单的表 OriginalValidLeaders,其中有一列 LeaderType

Leader A
Leader B
Leader C

现在我想将它们随机分配,例如(如果其中一些不交换也没关系):

Leader A | Leader C
Leader B | Leader A
Leader C | Leader B

this question 中,解决方案是使用row_number(),但是由于某种原因,我的 SQLite 不支持,所以我尝试了以下查询并且它有效:

SELECT L.LeaderType, R.LeaderType
FROM OriginalValidLeaders L
LEFT JOIN
    (
        SELECT LeaderType
        FROM OriginalValidLeaders
        ORDER BY random()
    ) R
ON L.rowid = R.rowid;

但老实说,这是我一次运气尝试的结果,我不明白它为什么会起作用。起初我尝试了INNER JOIN(这对我来说更有意义)但没有返回任何结果。

所以我的问题是:

  • 为什么 LEFT JOIN 有效,而 INNER JOIN 无效?
  • 这是否总是适用于所有情况?

测试架构/数据(归功于 forpas):

CREATE TABLE OriginalValidLeaders (LeaderType TEXT);

INSERT INTO OriginalValidLeaders (LeaderType) VALUES
('Leader A'), ('Leader B'), ('Leader C');

【问题讨论】:

  • 您需要 sqlite 3.25 或更高版本的窗口函数,如 row_number(),顺便说一句。
  • 除了左连接做一件事而内连接做另一件事之外,你还能期待什么答案?他们如何工作是一个常见问题。如果您不告诉我们您对每个案例的期望,我们怎么能告诉您您的信念和/或推理在哪里是错误或正确的?为什么说“它有效”?测试用例不能显示没有错误。 ORDER BY 在没有 TOP/LIMIT 的子查询中什么都不做。请参阅How to Ask 和投票箭头鼠标悬停文本。 PS 了解 LEFT JOIN ON 返回什么: INNER JOIN ON rows UNION ALL 不匹配的左表行,由 NULL 扩展。作为 OUTER JOIN 的一部分,始终知道您想要什么 INNER JOIN。
  • 请在代码问题中给出minimal reproducible example--剪切&粘贴&运行代码;具有期望和实际输出的示例输入(包括逐字错误消息);明确的规范和解释。这包括您可以提供的最少代码,即您显示的代码可以通过您显示的代码扩展为不正常。 (调试基础。) PS 表没有顺序。查询结果有(部分)顺序。
  • @philipxy 抱歉,感谢您提供的信息。我很少问关于数据库的问题,所以我还不熟悉。我已将其添加到问题中。下次我一定会记得的。

标签: sqlite join random left-join inner-join


【解决方案1】:

您必须使用旧版本的 SQLite
确实,相同的查询(带有LEFT JOIN 的查询)针对不同的版本返回不同的结果:
--------SQLite 3.8

a        | b       
-------- | -------
Leader A | Leader B
Leader B | Leader C
Leader C | Leader A

demo

--------SQLite 3.26

| a        | b   |
| -------- | --- |
| Leader A |     |
| Leader B |     |
| Leader C |     |

demo

我不知道这是否是一个错误,现在已在较新的版本中得到纠正。
在这两个版本中,INNER JOIN 查询都不会返回任何行。
但是如果你只是添加它:

ORDER BY L.rowid

然后它工作正常。
请参阅 demo for 3.8demo for 3.26

现在,子查询的rowid 是什么?
事实上,它以列的形式存在,但它是null
请参阅demo for 3.8demo for 3.26

【讨论】:

  • 哇,非常感谢。原来这是意外的错误?我的 sqlite_version() 正在返回 3.15.2。不幸的是,我正在修改游戏并且升级版本是不可能的。
  • 顺便说一句,即使没有返回结果,如果你运行 COUNT(*) 查询,它仍然返回 3,而不是 0。
  • 如果你运行 COUNT() 查询,它仍然返回 3,而不是 0* 是的,如果你运行内部连接查询,它也会在 DB Browser for SQLite 中返回查看 3 行的索引,但仅此而已。我想这是一个错误。我无法解释这种行为。
  • 谢谢,我已经举报the issue。将查看是 DB Browser UI 错误还是 SQLite 错误。
猜你喜欢
  • 2012-09-26
  • 2015-03-10
  • 2018-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
相关资源
最近更新 更多