postgresql 如何在SQL中避免叉积/笛卡尔/完全连接?

ohtdti5x  于 2023-03-22  发布在  PostgreSQL
关注(0)|答案(1)|浏览(125)

我们有一个表A,其中列“ETA到目的地”(分钟)。
| 身份证|预计到达时间(分钟)|得分|
| - ------|- ------|- ------|
| 1个|四十五||
| 第二章|七十五||
有一个配置表,我们已经根据时间间隔定义了分数。
例如-如果ETA在31至60分钟之间,则得分为5分,ETA在61至120分钟之间,则得分为10分,
| 从时间|至时间|得分|
| - ------|- ------|- ------|
| 无|三十|第二章|
| 三十一|六十|五个|
| 六十一|一百二十|十个|
我们需要根据配置表中的ETA分钟数(从时间到时间之间)找到分数(在表A中)。
我不想写一个在表中进行顺序扫描的完全连接。有更好的选择或更好的设计吗?
A可以有数百万条记录,而配置表可以有更少附加时间间隔行。

1aaf6o9v

1aaf6o9v1#

SELECT a.id, a.eta, s.score
FROM   a
JOIN   score_tbl s ON a.eta BETWEEN s.from_time AND s.to_time
ORDER  BY a.eta DESC NULLS LAST  -- how to break ties??
LIMIT  50;

a(eta)上有一个匹配索引来支持这个查询,这只是毫秒的问题。你在评论中提到的LIMIT 50让一切都变得不同。理想情况下:

CREATE INDEX a_eta_id_idx on a (eta DESC NULLS LAST) INCLUDE (id);

我们可以保持简单,因为更高的eta与更高的score相关。
具体细节取决于未公开的信息。基本上,***任何***以eta为前导或唯一列的B树索引都可以。但你必须符合尚未公开的规范,如何打破联系。
DESC NULLS LAST仅当eta可以是null(未定义NOT NULL)。否则仅为DESC。参见:

  • 按列ASC排序,但NULL值优先?

如果eta上可能存在重复项,则必须定义如何打破联系。我的查询进行了任意选择。但这对于正确的分页来说还不够好。请参阅:

  • SQL语法术语“WHERE(col1,col2)〈(val1,val2)”

相关问题