回答

收藏

如果在查询中的多个位置重复一个不相关的子查询,可以缓存并重复使用结果吗

技术问答 技术问答 215 人阅读 | 0 人回复 | 2023-09-14

如果我有类似的查询
  J/ s! X& D0 b/ ]0 T6 D4 rSELECT date_trunc('day',assigndate)e,      count(CASE WHEN a.assigneeid =         AND a.assigneeid IN               (SELECT userid                FROM groupmembers                WHERE groupid = 65553) THEN 1 ELSE NULL END) assigned,      count(CASE WHEN a.assigneeid =         AND a.completedtime IS NOT NULL             AND a.assigneeid IN               (SELECT userid                FROM groupmembers                WHERE groupid = 65553) THEN 1 ELSE NULL END) completedFROM ASSIGNMENT aWHERE assigndate > CURRENT_TIMESTAMP - interval '20 days'GROUP BY date_trunc('day',assigndate);有问题的子查询是
; p. O5 z; N# k% ^SELECT userid                FROM groupmembers                WHERE groupid = 65553然后,因为子查询是not co-related父亲查询的子查询,因此只执行一次,并将使用缓存结果。但由于子查询存在于查询中的两个位置,因此根据子查询SQL plan将被评估
% u3 Z- D6 O- M! {# s. M% Y  d两次    。有什么办法可以?cache得到子查询结果并在两个位置使用?. z' Z$ }4 l$ ]6 R: w2 A
子查询不能转换为连接,因为它不能转换为连接的单个字段(它不能无条件连接,因为计数会变错)。1 f5 T# d5 C9 q  O: f( b
                                                               
5 g- O( r+ W  j* Z    解决方案:                                                               
+ D: ~7 u& ~! w                                                                可以用通用表表达表达(WITH)
$ K% L) O- ?$ j  [6 Kwith cte as (     SELECT userid FROM groupmembers WHERE groupid = 65553)SELECT     date_trunc('day',assigndate)e,     count(CASE WHEN a.assigneeid = 65548 AND a.assigneeid IN             (SELECT userid from cte) then 1 else null end) assigned,...
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则