我正在尝试更新每组商品代码的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)
答案 0 :(得分: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 :(得分: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;
我没有对此进行测试或调试,但这将大致适合您。