【问题标题】:unable to use LIMIT when using correlated query使用相关查询时无法使用 LIMIT
【发布时间】:2023-03-12 00:37:02
【问题描述】:

我在 Postgres 中有两个表。我想从表中获取最新的 3records 数据。

下面是查询:

select two.sid as sid,
       two.sidname as sidname,
       two.myPercent as mypercent,
       two.saccur as saccur,
       one.totalSid as totalSid 
from table1 one,table2 two 
where one.sid = two.sid;

上面的查询显示了检查条件 one.sid = two.sid 的所有记录;我只想从 table2 中获取最近的 3 条记录 data(4,5,6)。

我知道在 Postgres 中我们可以使用 limit 来限制要检索的行,但是在 table2 中,每个 ID 我都有多行。所以我想我不能在 table2 上使用限制,但应该在 table1 上使用。有什么建议吗?

表1:

sid totalSid
1   10
2  20
3  30
4  40
5  50
6  60

表2:

sid sidname myPercent saccur 
1   aaaa        11    11t
1   bbb         13    13g
1   ccc         11    11g
1   qw          88    88k
//more data for 2,3,4,5....
6    xyz    89    895W     
6    xyz1       90    90k
6    xyz2       91    91p
6    xyz3       92    92q

【问题讨论】:

  • 用你的限制查找cross apply 的使用,而不是cross join, 连接我认为posgresql 称之为横向连接。 stackoverflow.com/questions/11472790/…你如何识别“最近”?
  • 或者使用窗口函数,比如row_number()。
  • 所以我不能在上述场景中使用 LIMIT?
  • 单独的限制是行不通的,因为它适用于整个连接集。因此,您无法获得每个 SID 的前 3 个。但是,当与横向连接结合使用时;该限制适用于每个连接值 (SID) 的 1 到 2 之间的每个连接
  • 如何识别table2中的“Recent”?

标签: sql postgresql greatest-n-per-group


【解决方案1】:

鉴于对问题的理解发生了变化,一个简单的子查询和连接就足够了。

我们在 sid order desc 中选择从 table1 限制到 3 条记录的所有内容。这为我们提供了 3 个最近的 SID,然后加入到 table2 以获取其他 SID 相关数据。这里的假设是 SID 在表 1 中是唯一的,“最近”将是那些具有最高 SID 的记录。

SELECT two.sid as sid
     , two.sidname as sidname
     , two.myPercent as mypercent
     , two.saccur as saccur
     , one.totalSid as totalSid 
FROM  (SELECT * FROM table1 ORDER BY SID DESC LIMIT 3) one
INNER JOIN table2 two 
  ON one.sid = two.sid;

*注意我在上面的一个别名后删除了一个逗号。

下面我们使用 , 表示法恢复了 ANSI 88 连接语法。

SELECT two.sid as sid
     , two.sidname as sidname
     , two.myPercent as mypercent
     , two.saccur as saccur
     , one.totalSid as totalSid 
FROM (SELECT * FROM table1 ORDER BY SID DESC LIMIT 3) one
   , table2 two 
WHERE one.sid = two.sid;

这个语法基本上是说从表一中获取 3 个最近的 SID 并交叉连接(对于一个中的每个记录,它与两个中的所有记录匹配)到表二中的所有记录,然后只返回具有相同 SID 的记录两侧。现代编译器可能能够使用基于成本的优化来提高性能,从而无需进行整个交叉连接;但是,操作顺序表明这是数据库通常必须执行的操作。如果一个和两个都是相当大的表,你可以看到交叉连接可能会导致一个非常大的临时数据集

【讨论】:

  • 是的,我们可以。我在上面的第二个 SQL 语句中重新审视了 ansi 89 标准。
  • 根据“SETS”处理/考虑数据,您需要一组最近的 3 个 SID 数据,然后您需要改进该组以包含表 2 中的相关信息。所以我们第一次得到一组最近的 3 条记录,然后我们加入表 2 以获取相关信息。通过使用子查询,我们强制引擎“生成”该集合,然后我们能够使用它来限制表 2 中的数据!就这么简单
  • 大声笑@I've revisited the ansi 89 standard。下一步是如果引擎没有实现 LIMIT(in subqueries...)
  • 我会回到 row_number。如果那不可用,那么我将返回从程序集堆栈中推送和弹出数据。天哪,我们距离 89 标准只有 28 年……不妨在技术世界中使用它。我的意思是 pft 在过去的 28 年里计算机到底走了多远...... Oo :P 公平地说,user7833845 我明白了;我知道我们有限制,我们会在必要时遵守。
猜你喜欢
  • 2023-03-21
  • 2017-10-31
  • 2019-08-16
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-04
  • 1970-01-01
相关资源
最近更新 更多