5

次のようなクエリがある場合

SELECT date_trunc('day', assigndate)e,
       count(CASE WHEN a.assigneeid = 65548
             AND a.assigneeid IN
               (SELECT userid
                FROM groupmembers
                WHERE groupid = 65553) THEN 1 ELSE NULL END) assigned,
       count(CASE WHEN a.assigneeid = 65548
             AND a.completedtime IS NOT NULL
             AND a.assigneeid IN
               (SELECT userid
                FROM groupmembers
                WHERE groupid = 65553) THEN 1 ELSE NULL END) completed
FROM ASSIGNMENT a
WHERE assigndate > CURRENT_TIMESTAMP - interval '20 days'
GROUP BY date_trunc('day',assigndate);

問題のサブクエリは

SELECT userid
                FROM groupmembers
                WHERE groupid = 65553

サブクエリはnot co-related親クエリに対するものであるため、一度だけ実行され、キャッシュされた結果が使用されます。ただし、サブクエリはクエリ内の 2 つの場所に存在するため、 に従って、2 回SQL plan評価されます。そのサブクエリの結果を取得し、両方の場所で使用する方法はありますか?cache

結合する単一のフィールドがないため、サブクエリを結合に変換することはできません (カウントが正しくなくなるため、無条件の結合にすることはできません)。

4

2 に答える 2

12

共通テーブル エクスプレス ( WITH)を使用できます。

with 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,
...
于 2012-10-22T12:46:12.353 に答える
1

サブクエリを削除するには、クエリを書き直す必要があります。

SELECT date_trunc('day', assigndate)e,
       sum(CASE WHEN a.assigneeid = 65548 and gm.userid is not null then 1 else 0
           end) as assigned,
       sum(CASE WHEN a.assigneeid = 65548 and a.completedtime IS NOT NULL and gm.userid is not null
                then 1 else 0
           end) as completed
FROM ASSIGNMENT a left outer join
     (select distinct userid
      from groupmembers
      where groupid = 65553
     ) gm
     on a.assigneeid = gm.userid
WHERE assigndate > CURRENT_TIMESTAMP - interval '20 days'
GROUP BY date_trunc('day',assigndate)
order by 1

FROM一般に、 (またはWITH) 句でテーブル参照を保持することをお勧めします。SELECT句内のサブクエリのロジックをたどるのは難しい場合があります。この場合、サブクエリは非常に類似しているため、実質的に 1 つのステートメントに結合する必要があります。

于 2012-10-22T14:03:14.010 に答える