我在SQL Server中的下表:
**Table: Volpartition**
Year Item Week Vol Part1 Part2
2013 1 wk20 0 0 0
2013 1 wk21 0 0 0
2013 1 wk22 300 300 0
2013 1 wk23 30 30 0
2013 1 wk24 400 400 0
2013 1 wk25 500 500 0
2013 1 wk26 60 60 0
2013 1 wk27 60 60 0
2013 2 wk20 0 0 0
2013 2 wk21 0 0 0
2013 2 wk22 300 300 0
2013 2 wk23 30 30 0
2013 2 wk24 400 400 0
2013 2 wk25 500 500 0
2013 2 wk26 60 60 0
2013 2 wk27 60 60 0
注意:part1和part2是vol。
的分区我想覆盖当前的表格,所需的结果应如下所示:
Year Item Week Vol Part1 Part2
2013 1 wk20 0 0 0
2013 1 wk21 0 0 0
2013 1 wk22 300 300 0
2013 1 wk23 30 30 0
2013 1 wk24 400 400 0
2013 1 wk25 500 0 500
2013 1 wk26 60 0 60
2013 1 wk27 60 0 60
2013 2 wk20 0 0 0
2013 2 wk21 0 0 0
2013 2 wk22 300 300 0
2013 2 wk23 30 30 0
2013 2 wk24 400 400 0
2013 2 wk25 500 0 500
2013 2 wk26 60 0 60
2013 2 wk27 60 0 60
逻辑是这样的:如果我有vol=0 the week before
那么可以拥有vol=part1
,然后最多可以持续3周。在此期间vol=part2
。
我希望你能理解表格列,我无法插入图片。
非常感谢任何建议!
答案 0 :(得分:0)
你的问题不明确,所以让我猜一下。在MSSQL中,您可以使用LAG()函数与当前行的偏移量。 如果您需要选择,请尝试:
WITH CTE AS
(
select t.*,
LAG(Vol,3) OVER (ORDER BY Week) as L3,
LAG(Vol,2) OVER (ORDER BY Week) as L2,
LAG(Vol,1) OVER (ORDER BY Week) as L1
FROM t
)
SELECT
[Item],[Week],[Vol],
CASE WHEN L1=0 OR L2 = 0 OR L3 =0
THEN [Part1]
ELSE 0
END as PART1,
CASE WHEN L1=0 OR L2 = 0 OR L3 =0
THEN 0
ELSE Vol
END as PART2
FROM CTE
ORDER BY Week
如果您需要更新表格,请:
WITH CTE AS
(
select t.*,
LAG(Vol,3) OVER (ORDER BY Week) as L3,
LAG(Vol,2) OVER (ORDER BY Week) as L2,
LAG(Vol,1) OVER (ORDER BY Week) as L1
FROM t
)
UPDATE CTE
SET
PART1 =
CASE WHEN L1=0 OR L2 = 0 OR L3 =0
THEN [Part1]
ELSE 0
END,
PART2=
CASE WHEN L1=0 OR L2 = 0 OR L3 =0
THEN 0
ELSE Vol
END
WHERE Vol<>0;
<强> UPD:强>
而不是ORDER BY WEEK
我认为您应该提取周数并将其投放到Int
,以便为wk1
和wk100
制作正确的订单。像这样:
ORDER BY CAST(SUBSTRING(Week,3,1000) as INT)
<强> UPD2:强>
如果您的SQLServer版本不支持LAG()
功能,则可以计算以下字段,然后将L1,L2,L3
替换为CASE WHEN LI=0 OR L2=0 OR L3 = 0
CASE WHEN flag = 0
ISNULL((SELECT MIN(Vol) FROM t as t1
where
CAST(SUBSTRING(t.Week,3,1000) as INT)-
CAST(SUBSTRING(t1.Week,3,1000) as INT)
between 1 and 3
),0) as flag
答案 1 :(得分:0)
对于SQL Server 2008,这是一个没有LAG
的变体。它使用几个公用表表达式来获取可以正常的周数列表,然后使用一个简单的CASE
来设置正确的值更新。
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY week) rn FROM Table1
), cte2 AS (
SELECT c1.week FROM cte c1, cte c2
WHERE c2.vol=0 AND c1.rn IN (c2.rn+1, c2.rn+2, c2.rn+3)
)
UPDATE Table1
SET Part1 = CASE WHEN Week IN (SELECT * FROM cte2) THEN Vol ELSE 0 END,
Part2 = CASE WHEN Week IN (SELECT * FROM cte2) THEN 0 ELSE Vol END;
请注意,此查询目前不需要考虑年份,因为它不在您提供的示例数据中。
编辑:这是一个将项目和年份考虑在内的版本;
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY item ORDER BY year, week) rn
FROM volpartition
), cte2 AS (
SELECT DISTINCT c1.item, c1.year, c1.week
FROM cte c1 JOIN cte c2 ON c1.item=c2.item
AND c1.rn IN (c2.rn+1, c2.rn+2, c2.rn+3)
WHERE c2.vol=0
)
UPDATE v
SET Part1 = CASE WHEN c.item IS NULL THEN 0 ELSE Vol END,
Part2 = CASE WHEN c.item IS NULL THEN Vol ELSE 0 END
FROM volpartition v
LEFT JOIN cte2 c ON v.item = c.item AND v.year = c.year AND v.week = c.week;