我正试图确定零件从完成到销售的时间(试图弄清楚库存中的库存时间是否太长)
我的数据如下:
| SaleID | ProductFinished | ProductSold |
|:------:|:---------------:|:-----------:|
| 100 | 5/1/2019 | 6/1/2019 |
| 200 | 7/1/2019 | 7/3/2019 |
| 300 | 6/23/2019 | 6/30/2019 |
| 400 | 6/20/2019 | 6/21/2019 |
| 500 | 4/21/2019 | 5/21/2019 |
| 600 | 5/11/2019 | 6/20/2019 |
And here is an SQL Fiddle with that table
我需要计算当前行的ProductSold
值和上一行的ProductFinished
值之间的差,然后将该差分配给当前行的SittingTimer
列。我的目标数据集如下:
| SaleID | ProductFinished | ProductSold | SittingTimer |
|:------:|:---------------:|:-----------:|:------------:|
| 100 | 5/1/2019 | 6/1/2019 | NULL |
| 200 | 7/1/2019 | 7/3/2019 | 63 |
| 300 | 6/23/2019 | 6/30/2019 | -1 |
| 400 | 6/20/2019 | 6/21/2019 | -2 |
| 500 | 4/21/2019 | 5/21/2019 | -30 |
| 600 | 5/11/2019 | 6/20/2019 | 60 |
我已经阅读了Oracle's LAG
function,并且看到了一些使用LAG
的帖子like this,但是我似乎无法使其正常工作。
我尝试了以下操作:
SELECT
tblSales.*,
TO_NUMBER(LAG(ProductFinished - ProductSold, 1, 0) OVER (ORDER BY SaleID)) AS SittingTimer
FROM
tblSales
但是得到这个结果是
SALEID PRODUCTFINISHED PRODUCTSOLD SITTINGTIMER
100 2019-04-30T00:00:00Z 2019-05-31T00:00:00Z 0
200 2019-06-30T00:00:00Z 2019-07-02T00:00:00Z -31
300 2019-06-22T00:00:00Z 2019-06-29T00:00:00Z -2
400 2019-06-19T00:00:00Z 2019-06-20T00:00:00Z -7
500 2019-04-20T00:00:00Z 2019-05-20T00:00:00Z -1
600 2019-05-10T00:00:00Z 2019-06-19T00:00:00Z -30
我要去哪里错了?我应该避免使用LAG
吗?
答案 0 :(得分:2)
使用以下查询,您需要lead()
分析函数
SELECT
tblSales.*, lead("ProductSold") over(order by "SaleID")-"ProductFinished" as prf
FROM
tblSales
输出
SaleID ProductFinished ProductSold SITTINGTIMER
100 2019-04-30 20:00:00.0 2019-05-31 20:00:00.0 63 0:0:0.0
200 2019-06-30 20:00:00.0 2019-07-02 20:00:00.0 -1 0:0:0.0
300 2019-06-22 20:00:00.0 2019-06-29 20:00:00.0 -2 0:0:0.0
400 2019-06-19 20:00:00.0 2019-06-20 20:00:00.0 -30 0:0:0.0
500 2019-04-20 20:00:00.0 2019-05-20 20:00:00.0 60 0:0:0.0
600 2019-05-10 20:00:00.0 2019-06-19 20:00:00.0 (null)
答案 1 :(得分:2)
您应该从滞后结果中减去当前行的值;不能在滞后函数中减去:
SELECT
tblSales.*,
LAG("ProductFinished", 1) OVER (ORDER BY "SaleID") - "ProductSold" AS SittingTimer
FROM
tblSales;
SaleID ProductFinished ProductSold SITTINGTIMER
---------- ----------------------- ----------------------- ------------
100 30-Apr-2019 08:00:00 PM 31-May-2019 08:00:00 PM
200 30-Jun-2019 08:00:00 PM 02-Jul-2019 08:00:00 PM -63
300 22-Jun-2019 08:00:00 PM 29-Jun-2019 08:00:00 PM 1
400 19-Jun-2019 08:00:00 PM 20-Jun-2019 08:00:00 PM 2
500 20-Apr-2019 08:00:00 PM 20-May-2019 08:00:00 PM 30
600 10-May-2019 08:00:00 PM 19-Jun-2019 08:00:00 PM -60
6 rows selected.
这使您“当前行的ProductSold值与上一行的ProductFinished值之间存在差异”;交换那些值的符号会更改值的减去顺序:
SELECT
tblSales.*,
"ProductSold" - LAG("ProductFinished", 1) OVER (ORDER BY "SaleID") AS SittingTimer
FROM
tblSales;
SaleID ProductFinished ProductSold SITTINGTIMER
---------- ----------------------- ----------------------- ------------
100 30-Apr-2019 08:00:00 PM 31-May-2019 08:00:00 PM
200 30-Jun-2019 08:00:00 PM 02-Jul-2019 08:00:00 PM 63
300 22-Jun-2019 08:00:00 PM 29-Jun-2019 08:00:00 PM -1
400 19-Jun-2019 08:00:00 PM 20-Jun-2019 08:00:00 PM -2
500 20-Apr-2019 08:00:00 PM 20-May-2019 08:00:00 PM -30
600 10-May-2019 08:00:00 PM 19-Jun-2019 08:00:00 PM 60
它还假设您的列是日期而不是时间戳-因为如果查询是时间戳,则查询会因ORA-00932错误而出错;但我还是保留了SQL Fiddle中带引号的标识符,因为它们必须出于某种原因而存在。 (您的问题数据和查询与您的小提琴不匹配会令人困惑...)
答案 2 :(得分:0)
如果您使用时间戳,则需要使用时间戳中的提取日期来找到所需的结果,如下所示:
SELECT
"SaleID",
"ProductFinished",
"ProductSold",
EXTRACT(DAY FROM "ProductSold" - LAG("ProductFinished") OVER(
ORDER BY
"SaleID"
)) AS SITTINGTIMER
FROM
TBLSALES
输出:
干杯!