【问题标题】:Extracting the data minus day using LEAD function使用 LEAD 函数提取数据减去天数
【发布时间】:2020-06-05 07:43:15
【问题描述】:

我的表 PRODUCTINFO 有 2 列:PRODUCTID (NUMBER)ALLOWFROM (DATE),现在我需要再插入一列 ALLOWTO (DATE),它等于下一行中的 ALLOWFROM 减去 1 天。如果PRODUCTID 没有下一个ALLOWFROM,则应打印'01-01-1900'

CREATE TABLE PRODUCTINFO (
    PRODUCTID NUMBER (8,0)
    ALLOWFROM DATE    
);

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (1, '05.01.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (1, '06.05.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (1, '06.10.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (1, '06.20.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (2, '05.01.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (2, '06.18.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (3, '05.01.2018')

INSERT INTO PRODUCTINFO
 (PRODUCTID, ALLOWFROM)
VALUES (3, '06.08.2018')

我尝试执行此脚本,但没有结果:

SELECT PRODUCTID, ALLOWFROM,
    LEAD(ALLOWTO, 3,'01-01-1900') OVER (ORDER BY ALLOWFROM) - 1 AS ALLOWTO
    FROM PRODUCTINFO
    ORDER BY PRODUCTID, ALLOWFROM;

我哪里错了?如何达到结果?

【问题讨论】:

  • 这是 oracle 还是 mysql ?这是两种不同的数据库技术。请调整您的标签。
  • LEAD/LAG 是分析函数,允许您访问查询的上一行/下一行。根据您的解释,您不需要上一行,而只需要上一个日期值。尝试 NVL(ALLOWTO,TO_DATE('02-JAN-1900','DD-MON-YYYY') - 1 代替。
  • 我已经删除了所有冲突的标签。 MySQL 和 Oracle 是完全不同的 RDBMS,都不使用 T-SQL(由 SQL Server 使用)。请仅重新标记您实际使用的内容。
  • 嗨@KoenLostrie!正如我所解释的,我需要新列(表中的第三列)ALLOW_TO,它等于下一个 ALLOWFROM(第二列)减去一天。这就是我使用 LEAD 访问下一个 ALLOWFROM 行的原因。
  • @hatorihanso。请提供适当的可重现示例:创建表脚本,插入示例行。这使我们更容易理解实际问题。图片看起来很棒,但我无法将它们复制到 sqldeveloper 中运行...stackoverflow.com/help/minimal-reproducible-example

标签: sql oracle window-functions


【解决方案1】:

这是你需要的吗? 我按产品 ID 订购(这不在您的问题中,但似乎很明显)。建议您阅读 LEAD/LAG 上的 documentation 以熟悉这些论点。

SELECT productid,
       allowfrom,
       LEAD(allowfrom - 1,1, TO_DATE('01.01.1900', 'MM.DD.YYYY')) 
         OVER(PARTITION BY productid ORDER BY allowfrom ASC) AS allowto
  FROM productinfo;

 PRODUCTID ALLOWFROM  ALLOWTO   
---------- ---------- ----------
         1 05.01.2018 06.04.2018
         1 06.05.2018 06.09.2018
         1 06.10.2018 06.19.2018
         1 06.20.2018 01.01.1900
         2 05.01.2018 06.17.2018
         2 06.18.2018 01.01.1900
         3 05.01.2018 06.07.2018
         3 06.08.2018 01.01.1900

【讨论】:

  • 一点也不。如果某个 PRODUCTID 没有下一行,我会尝试打印“01-01-1900”。例如,我看到在第 4 行之后,PRODUCTID 2 消失了。因此,在这种情况下,我应该打印“01-01-1900”,因为 PRODUCTID 1 没有下一个 ALLOWFROM。
  • 在这种情况下,您需要按 productid 进行分区。正如我所说......你应该阅读文档,而不是我;)。我更新了答案
  • 你完全正确!非常感谢您的回答和文档链接。
【解决方案2】:

您可以在以下查询中使用LAG() 解析函数:

SELECT PRODUCTID, ALLOWFROM, 
       LEAD(ALLOWFROM - 1,1,date'1900-01-01') 
       OVER (PARTITION BY PRODUCTID ORDER BY PRODUCTID, ALLOWFROM) AS ALLOWTO
  FROM PRODUCTINFO
 ORDER BY PRODUCTID, ALLOWFROM;

其中日期文字被正确格式化为第三个参数,第二个参数中的值 1 是偏移量。

Demo

【讨论】:

  • 嗨!感谢您的答复。 LAG 用于访问上一行,但我需要下一行。这就是我使用 LEAD 功能的原因。
  • 不客气@hatorihanso,但你告诉:在下一行减去1天,我在之前的编辑中也使用了LEAD(),但如果这对你有帮助,我可以恢复。
猜你喜欢
  • 2023-04-03
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-24
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多