Sql MAX()作为左联接的筛选子句,是否有其他选择?
在我看来,这个查询还有另一个选项,但我无法准确指出该选项是什么:Sql MAX()作为左联接的筛选子句,是否有其他选择?,sql,sqlite,max,left-join,Sql,Sqlite,Max,Left Join,在我看来,这个查询还有另一个选项,但我无法准确指出该选项是什么: @Query("" + "SELECT " + "... not really important... " + "FROM (" + "SELECT ect.* " + "FROM element_constant_table ect &qu
@Query("" +
"SELECT " +
"... not really important... " +
"FROM (" +
"SELECT ect.* " +
"FROM element_constant_table ect " +
"WHERE book_parent_id = :bookId AND availability = 1" +
") ect1 " +
"LEFT JOIN " +
"element_version_table evt " +
"ON (" +
"SELECT evt.element_parent_id " +
"WHERE " +
"evt.time = (" +
"SELECT MAX(evt2.time) " +
"FROM element_version_table evt2 " +
"WHERE evt2.element_parent_id = evt.element_parent_id" +
") " +
") = ect1.element_id" +
"")
public abstract LiveData<List<Element>> getLatestElementsAt(int bookId);
MAX()函数强制对元素常量表
中的每一行执行整个元素版本表
的新实例化
我知道可能会发生类似的情况,所以我总是在表到达左联接之前尝试对其进行筛选,在本例中使用子句“WHERE book\u parent\u id=:bookId AND availability=1”
在on子句之前,无法过滤左表并使其与右表上相应的键一致,因此需要将WHERE放在那里
问题是,如果不使用MAX(),而是在ON子句中使用简单的ORDER BY evt.time DESC LIMIT 1,编译器会告诉我没有evt.time字段(我假设它还不存在)。
因此,我的结论是:
a)ORDER BY要求将表实例化为其完整长度(在行定位过程中不会发生)。
b)ON子句发生在左表的实例化(我假设是)达到其完整长度之前。
我关于条款执行顺序的结论正确吗
这个查询在一个庞大的数据库上会有多大的负担?和
更好的选择是什么?请使用下面的sql查询在代码中检索书籍的实时数据:
SELECT
... not really important...
FROM element_constant_table ect
LEFT JOIN
(SELECT evt.*, ROW_NUMBER() OVER (PARTITION BY evt.element_parent_id ORDER BY evt.time DESC) as seqnum
from element_version_table evt) evt_final on ect.element_id = evt_final.element_parent_id and evt_final.seqnum=1
where ect.book_parent_id = :bookId AND ect.availability = 1
我在这里找到“element\u version\u table”(如果存在)中的最新图书记录。SQLite窗口函数ROW\u NUMBER()可以解决您的问题 您没有提供表的全部详细信息。但是,根据element_版本表的大小和查询性能,您可以尝试:
SELECT
... not really important... FROM
(SELECT ect.*
FROM element_constant_table ect
WHERE book_parent_id=:bookId AND availability=1
) ect1
LEFT JOIN
(SELECT t.*
FROM
(SELECT
evt.*,
ROW_NUMBER() OVER (PARTITION BY element_parent_id ORDER BY evt.time DESC) rn
FROM element_version_table evt) t
WHERE t.rn = 1
) evt1
ON ect1.element_id = evt1.element_parent_id
或
此解决方案适用于SQLite版本<3.25.0
感谢用户@armamut提出了最初的想法和7年前的另一个问题
选择evt.element\u parent\u id WHERE…
FROM子句在哪里?是的,我有同样的疑问,但查询实际上是有效的,该表来自一个被称为“element\u version\u table evt”的表。。。。哦,这就是为什么找不到evt.time的原因吗???也许它可以工作,但您的查询不可读。发布示例数据和预期结果,以澄清您想要的内容。嘿,感谢您的回答,我相信这是可行的,但解决方案适用于SQLite版本,从3.25.0开始,以及超过3.25.0的版本,我的版本为3.19,但行数=1非常聪明,因为它避免了在关联之前裁剪表。分区方式是一种分组方式,这意味着你在有效地过滤左边的表,给你一个最上面的元素,以及每个按时间排序的组,我认为在3.19中没有办法做到这一点。在比赛开始之前。谢谢你的回答
SELECT
... not really important... FROM
(SELECT ect.*
FROM element_constant_table ect
WHERE book_parent_id=:bookId AND availability=1
) ect1
LEFT JOIN
(SELECT t.*
FROM
(SELECT
evt.*,
ROW_NUMBER() OVER (PARTITION BY element_parent_id ORDER BY evt.time DESC) rn
FROM element_version_table evt) t
WHERE t.rn = 1
) evt1
ON ect1.element_id = evt1.element_parent_id
SELECT t.*
FROM
(SELECT
... not really important...,
ROW_NUMBER() OVER (PARTITION BY ect1.element_id, evt1.element_parent_id ORDER BY evt1.time DESC) rn
FROM
(SELECT ect.*
FROM element_constant_table ect
WHERE book_parent_id=:bookId AND availability=1
) ect1
LEFT JOIN element_version_table evt1
ON ect1.element_id = evt1.element_parent_id
) t
WHERE t.rn = 1
@Query("" +
"SELECT " +
... not really important ...
"FROM (" +
"SELECT ect.* " +
"FROM element_constant_table ect " +
"WHERE book_parent_id = :bookId AND availability = 1" +
") ect1 " +
"LEFT JOIN " +
"(" +
"SELECT " +
"evt.*," +
"MAX(evt.time) " +
"FROM element_version_table evt " +
"GROUP BY evt.element_parent_id" +
") evt1 " +
"ON evt1.element_parent_id = ect1.element_id" +
"")
public abstract LiveData<List<Element>> getLatestElementsAt(int bookId);
SELECT
... not really important ...
FROM (
SELECT ect.*
FROM element_constant_table ect
WHERE book_parent_id = :bookId AND availability = 1
) ect1
LEFT JOIN
(
SELECT
evt.*,
MAX(evt.time)
FROM element_version_table evt
GROUP BY evt.element_parent_id
) evt1
ON evt1.element_parent_id = ect1.element_id