我正在寻找一种从下一行获取值的SQL方法。
我看到的数据如下:
CUST PROD From_Qty Disc_Pct
23 Brush 1 0
23 Brush 13 1
23 Brush 52 4
77 Paint 1 0
77 Paint 22 7
我最终需要做的是,(我想创建To_Qty行):
CUST PROD From_Qty To_Qty Disc_Pct
23 Brush 1 12 0
23 Brush 13 51 1 #13 is 12+1
23 Brush 52 99999 4 #52 is 51+1
77 Paint 1 21 0 #1 is 99999+1
77 Paint 22 99999 7 #22 is 21+1
我有100K +行来执行此操作,它必须是SQL,因为我的ETL应用程序允许SQL而不是存储过程等。
如何从下一行获取值,以便创建To_Qty?
答案 0 :(得分:2)
SELECT *,
LEAD([From_Qty], 1, 100000) OVER (PARTITION BY [CUST] ORDER BY [From_Qty]) - 1 AS To_Qty
FROM myTable
LEAD()会根据[From_Qty]
的顺序为您提供下一个值...您在PARTITION BY [CUST]
更改值时使用[Cust]
进行重置
或者您可以使用CTE和Row_Number。
WITH cte AS
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [CUST] ORDER BY [From_Qty]) Rn
FROM myTable
)
SELECT t1.*,
ISNULL(t2.From_Qty - 1, 99999) To_Qty
FROM cte t1
LEFT JOIN cte t2 ON t1.Cust = t2.Cust AND t1.Rn + 1 = t2.Rn
答案 1 :(得分:1)
如果您运行的是SQL Server 2012或更高版本,则可以使用LAG和LEAD函数来访问先前或后续行以及当前行。
答案 2 :(得分:0)
您可以使用LEAD和FIRST_VALUE分析函数生成您提到的结果。通过使用LEAD()函数,可以检索客户组中的下一个值,FIRST_VALUE()将在客户组中给出第一个值。
比如说。 CUST = 23 ...... LEAD将返回13并且FIRST_VALUE将返回1 ... TO_QTY = LEAD - FIRST_VALUE,即13-1 = 12。以类似的方式,下面提到的公式将计算表中所有100k行。
SELECT CUST,
PROD,
FROM_QTY,
CASE WHEN LEAD( FROM_QTY,1 ) OVER ( PARTITION BY CUST ORDER BY FROM_QTY ) IS NOT NULL
THEN
LEAD( FROM_QTY,1 ) OVER ( PARTITION BY CUST ORDER BY FROM_QTY ) -
FIRST_VALUE( FROM_QTY ) OVER ( PARTITION BY CUST ORDER BY FROM_QTY )
ELSE 99999
END AS TO_QTY,
DISC_PCT
FROM Yourtable;
答案 3 :(得分:0)
将数据插入到具有相同列的临时表中,但添加了id自动增量字段。插入它们有序,我假设是cust,prod,然后是from_qty。 现在,您可以在临时表上运行更新语句。
UPDATE #mytable
SET To_Qty = (SELECT From_Qty - 1 FROM #mytable AS next WHERE next.indexfield = #mytable.indexfield + 1 AND next.cust = #mytable.cust and next.prod = #mytable.prod)
然后另一个使用not exists子句执行99999。
然后将数据插回新的或修改过的表格。
答案 4 :(得分:0)
declare @Table table(CUST int, PROD varchar(50), From_Qty int, Disc_Pct int)
insert into @Table values
(23, 'Brush', 1, 0)
,(23, 'Brush', 13, 1)
,(23, 'Brush', 52, 4)
,(77, 'Paint', 1, 0)
,(77, 'Paint', 22, 7)
SELECT CUST, Prod, From_qty,
LEAD(From_Qty,1,100000) OVER(PARTITION BY cust ORDER BY from_qty)-1 AS To_Qty,
Disc_Pct
FROM @Table
答案 5 :(得分:0)
SELECT
CUST,
PROD,
FROM_QTY ,
COALESCE(MIN(FROM_QTY) OVER (PARTITION BY CUST, PROD ORDER BY FROM_QTY DESC ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) , 10000)-1,
DISC_PCT
FROM <tablename>
ORDER BY CUST, PROD, FROM_QTY