3

次の作業クエリがありますが、これを書くにはもっと簡単な方法が必要なようです。できる限りクエリをクリーンアップし、以下に貼り付けました。ヘルプ/アドバイスをいただければ幸いです。

サンプル結果:

UserID  | MemberCount | TotalCheck | TotalCCs
---------------------------------------------- 
123     |  75         |  25        | 0 
456     |  74         |  129       | 156

サンプルクエリ:

Select BPE.UserID
    ,ISNULL((Select COUNT(*) 
           From clients 
           where fac_id = BPE.billpay_FacID 
               and clt_web_type = 1 
               and clt_relationship = 0),'0') as MemberCount
    ,(Select SUM(achorder_total) as ACHTotal 
        from ACHOrder 
        where achorder_siteid = BPE.siteID 
                    and ACHOrder_PayDate between @Start and @End 
                    and ACHOrder_Status not in ('Voided','Reversed')) As TotalChecks
    ,(Select SUM(CCorder_total) as CCTotal 
        from CCOrder 
        where CCorder_siteid = BPE.siteID 
                    and CCOrder_PayDate between @Start and @End 
                    and CCOrder_Status not in ('Voided','Reversed')) As TotalCCs
From BillingEnabled BPE
Order By BPE.UserID

このクエリを作成する簡単な方法はありますか?

4

1 に答える 1

2

私の理解が正しければ、関係のない行セットを個別にカウント/合計したいですか? そこに多くの選択肢があるとは思いません。

私が使用するのは CROSS APPLY (またはその姉妹の OUTER APPLY) です。構文が少し変更されますが、おそらく実行計画はあまり変更されません (ただし、確認する必要があります。ここでは推測しているだけです)。

SELECT BPE.UserID, MemberCount.Value, TotalChecks.Value
FROM BillingEnabled BPE
CROSS APPLY (SELECT COUNT(*) as Value 
             FROM clients 
             WHERE fac_id = BPE.billpay_FacID and ...) MemberCount
OUTER APPLY (SELECT SUM(achorder_total) as Value 
             FROM ACHOrder 
             WHERE achorder_siteid = BPE.siteID AND ...) TotalChecks
ORDER BY 1

最初に完全な計算を行ってから結果を結合すると、実行計画が異なる可能性があります。これがより効率的か悪いかはわかりません。ユーザーの小さなサブセットを除いてすべてをクエリしない場合、最初の 2 つのクエリを何らかの方法で制限しないと、非常に非効率的になります。

WITH MemberCount AS
(
  SELECT fac_id, COUNT(*) as Value
  FROM clients
  WHERE clt_web_type = 1 AND clt_relationship = 0
  GROUP BY fac_id
),
TotalChecks AS
(
  SELECT achorder_siteid, SUM(achorder_total) as Value
  FROM ACHOrder
  WHERE ACHOrder_PayDate BETWEEN @Start AND @End 
    AND ACHOrder_Status NOT IN ('Voided','Reversed')) 
  GROUP BY achorder_siteid
)
SELECT BPE.UserId, MemberCount.Value, TotalChecks.Value
FROM BPE
LEFT OUTER JOIN MemberCount 
  ON MemberCount.fac_id = BPE.billpay_FacID
LEFT OUTER JOIN TotalChecks
  ON TotalChecks.achorder_siteid = BPE.siteID
ORDER BY 1
于 2013-06-10T23:22:01.727 に答える