0

誰かが同じ問題を解決するもっとエレガントな方法を持っている場合に備えて、私が試みていることを簡単に説明しましょう。データベース内の販売注文を調べ、同じ商品が同じ顧客によって複数回注文されたときを見つけ、以前の注文間隔の平均を使用して次の注文日を予測するストアド プロシージャを作成しようとしています。同じアイテム。以下のクエリは、おそらくカーソルと実行中の平均を処理するための一時テーブルの基礎を形成します。

これまでのところ、私が持っているクエリは次のようになります

SELECT    sl.custaccount ,
        sl.itemid ,
        sl.shippingdaterequested ,
        nextdate.shippingdaterequested AS nextshippingdaterequested
FROM      salesline AS sl
        OUTER APPLY ( SELECT TOP 1
                                sl2.custaccount ,
                                sl2.itemid ,
                                sl2.shippingdaterequested
                      FROM      salesline AS sl2
                      WHERE     sl2.shippingdaterequested > sl.shippingdaterequested
                                AND sl2.custaccount = sl.custaccount
                                AND sl2.itemid = sl.itemid
                      GROUP BY  sl2.custaccount ,
                                sl2.itemid ,
                                sl2.shippingdaterequested
                      ORDER BY  sl2.shippingdaterequested
                    ) AS nextdate
GROUP BY  sl.custaccount ,
        sl.itemid ,
        sl.shippingdaterequested ,
        nextdate.shippingdaterequested

このクエリは、その商品がその顧客によって次に注文された時間を表す列を含むすべての販売明細の行を提供します。その列が NULL の場合、現在のレコードが最後であることがわかります。

基本的な問題は、このクエリが遅すぎることです。一度に 1 人の顧客に対して実行すると問題なく実行され、1 秒で結果が返されますが、約 100,000 の顧客に対して実行すると約 27 時間かかります。

基本的な問題は、私が外側に適用していることであることを知っているので、おそらく行処理を苦しめることによって行を実行していますが、それを聞く別の方法がより速く機能するかどうかはわかりません。何かご意見は?

4

1 に答える 1

1

必要以上に複雑にしていると思います。
最小値と最大値を取り、カウントで割るだけです

SELECT  sl.custaccount ,
    sl.itemid ,
    MAX(sl.shippingdaterequested) AS lastShip ,
    DATEDIFF(dd, MIN(sl.shippingdaterequested),
             MAX(sl.shippingdaterequested)) / COUNT(*) AS interval ,
    DATEADD(dd,
            DATEDIFF(dd, MIN(sl.shippingdaterequested),
                     MAX(sl.shippingdaterequested)) / COUNT(*),
            MAX(sl.shippingdaterequested)) AS nextShip
FROM    salesline AS sl
GROUP BY sl.custaccount ,
    sl.itemid
HAVING  COUNT(*) > 1
于 2013-08-25T13:24:59.790 に答える