1

商品コードのグループごとに datedelta フィールドを更新しようとしています。datedelta フィールドには、特定の商品が最後に販売されてからの日数が含まれているはずです。たとえば、更新前のテーブルは次のようになります。

表:「売上」

   id      date       datedelta    itemcode
  --------------------------------------------
    1    2012-09-01     null          1
    2    2012-09-08     null          1
    3    2012-09-20     null          1
    4    2012-03-01     null          2
    5    2013-06-01     null          3
    6    2013-06-06     null          3

更新後、テーブルは次のようになります。

   id      date       datedelta    itemcode
  --------------------------------------------
    1    2012-09-01       0           1
    2    2012-09-08       7           1
    3    2012-09-20      12           1
    4    2012-03-01       0           2
    5    2013-06-01       0           3
    6    2013-06-06       5           3

以下の点で困っています。

a) 自己結合を行い、前の日付のレコードを参照する方法、および

b) グループ化部分の処理方法。つまり、日付の違いは、同じ品目コードに対してのみ計算されます。

次のクエリを試しましたが成功しませんでした:

UPDATE sales AS s
INNER JOIN sales AS prev 
ON prev.id IN (SELECT t.id FROM sales WHERE MAX(t.saledate) < r.saledate GROUP BY itemcode ORDER BY itemcode) 
SET datedelta = IFNULL(DATEDIFF(r.saledate, p.saledate), 0)
4

2 に答える 2

0

連続するレコードのギャップを見つけるという質問に対して、Cursors を使用してレコードを反復処理するのは楽しいと思います。ここではあまり使用されていませんが、複雑な自己結合などよりも頭を包み込むのが簡単だと思います.

CREATE PROCEDURE findgaps()
    BEGIN    

    DECLARE done INT DEFAULT FALSE;
    DECLARE idv, datedeltav, itemcodev, prev_itemcodev INT;
    DECLARE datev, prev_datev DATE;

    DECLARE cur CURSOR FOR SELECT id, date, datedelta, itemcode
                           FROM sales
                           ORDER BY itemcode ASC, date ASC;

    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;       

    read_loop: LOOP
        SET prev_datev = datev;
        SET prev_itemcodev = itemcodev;
        FETCH cur INTO idv, datev, datedeltav, itemcodev;   
        IF done THEN
            LEAVE read_loop;
        END IF;
        IF NOT itemcodev <=> prev_itemcodev THEN
           SET prev_datev = datev;
        END IF;
        UPDATE sales s
        SET s.datedelta = DATEDIFF(datev,prev_datev)
        WHERE s.id = idv;
    END LOOP;    

    CLOSE cur;  

    END;

私はこれをテストしたりデバッグしたりしていませんが、これで大まかに実行できます。

于 2013-08-13T20:00:35.510 に答える
0

結合でこれを行うことができますが、相関サブクエリを使用する方が簡単です。

UPDATE sales s
     set s.datedelta = coalesce(datediff((select sprev.racedate
                                          from sales sprev
                                          where sprev.itemcode = s.itemcode and
                                                sprev.racedate < s.racedate
                                          order by sprev.racedate desc
                                          limit 1
                                         ), rprev.racedate
                                        ), 0);

クエリに関して、少なくとも 1 つの問題は、列で使用されるテーブルのエイリアスが、テーブルに定義されたエイリアスと一致しないことです。

于 2013-08-13T15:16:13.677 に答える