我有以下 SQL,它选择论坛线程,其中包含有关第一个/最后一个帖子、帖子数量和启动它的用户的随附信息:
SELECT forum_threads.*,
users.displayname as cc_username,
coalesce(count(forum_posts.id),0) AS cc_postCount,
(select id from forum_posts where threadId=forum_threads.id order by tsCreate asc limit 1) as cc_firstPostId,
(select id from forum_posts where threadId=forum_threads.id order by tsCreate desc limit 1) as cc_lastPostId,
(select tsCreate from forum_posts where threadId=forum_threads.id order by tsCreate desc limit 1) as cc_tsLatest
FROM forum_threads
LEFT JOIN forum_posts ON forum_posts.threadId = forum_threads.id
LEFT JOIN users ON users.id = forum_threads.userId
GROUP BY forum_threads.id
ORDER BY forum_posts.tsCreate DESC
它似乎工作正常,但我刚刚在教程点上阅读SQLite子查询不能包含ORDER BY
。我的有,他们工作。
它们是如何工作的?我只是幸运吗,我应该以其他方式构建我的查询吗?
您正在生成的子查询的类型在 SQL 中称为标量子查询。 这是一个返回一列最多一行的子查询。 例如,它计算单个值,可用于select
和where
子句。
表达式的文档描述了标量子查询:
子查询表达式
。
返回单个列的子查询是标量子查询,可以在任何地方使用。返回两个或更多列的子查询是行值子查询,只能用作比较运算符的操作数。
关于order by
的使用没有区别。
实际上,您的子查询类型实际上是一个标量相关的子查询,但相同的推理也适用。
我应该注意的是,SQLite 中表达式的语法图似乎缺少标量子查询。 所以文档对此进行了解释。 我认为这是文档中的错误。
尽管可以使用教程作为指导,但如果您确实想知道数据库的作用,请查看该数据库的文档。