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) 如何处理分组部分。即,仅针对相同的 itemcode 计算日期差异。

我尝试了以下查询但没有成功:

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

虽然您可以使用连接来完成此操作,但我发现使用相关子查询更容易:

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);

至于您的查询,至少有一个问题是与列一起使用的表别名与为表定义的别名不匹配。

于 2013-08-13T15:16:13.677 回答
0

对于在连续记录中查找空白的问题,我发现使用光标遍历记录很有趣。我没有看到它们在这里经常使用,但我认为它们比有时复杂的自连接等更容易缠绕头部。

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 回答