Oracle SQL LAG 函数

Posted

技术标签:

【中文标题】Oracle SQL LAG 函数【英文标题】:Oracle SQL LAG Function 【发布时间】:2017-01-27 13:26:07 【问题描述】:

感谢您对这段代码的帮助,我收到“缺少关键字”错误。我以前从未使用过 Lag 功能,所以希望我能正确使用它。谢谢你的帮助。加夫

CREATE VIEW GS_Date AS
SELECT                        
        DATE_DATE, 
        DATE_FLAG,
        CASE WHEN  LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE ) = '1' THEN DATE_STEP = ( LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE ) ) + '1'
                 WHEN  LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE ) = '0' AND LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE ) =  '-1'  THEN DATE_STEP = ( LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE ) ) + '1'
                 ELSE DATE_STEP = LAG ( DATE_FLAG)  OVER ( ORDER BY DATE_DATE )  END AS DATE_STEP
FROM DATE_GROUP                  

【问题讨论】:

您不能在 SQL 语句中使用 DATE_STEP = ... 分配变量或列。与错误无关:lag() 返回一个数字,不要将其与字符串进行比较。 '1' 是一个字符串常量。 1 是一个数字。 要查找错误,暂时跳过案例,一次尝试一个LAG。 感谢您的帮助,现在正在工作。 @jarlh - 除了在这个例子中,错误与 CASE 的使用方式有关; LAG 完全没问题! @Gavin - 如果它正在“工作”,这意味着你发现你错误地使用了 CASE。应该是CASE when... then... (just the value), etc as DATE_STEP 【参考方案1】:

问题在于 CASE 表达式;你正确地使用了 LAG。

其他要点:不要将'1''-1' 之类的字符串添加到数字中。添加数字 - 您不需要单引号。

另外,如果在计算中某些东西是常见的并且只有“最后一部分”不同,您可以使用 CASE 表达式“在末尾”。如下:

注意:重新阅读原帖时,公式需要更复杂(我没有完全正确)。不改变答案,因为它仍然说明了我想要分享的相同想法。但是:查看原始帖子,有一个条件“when LAG = 0 and LAG = -1” - 这永远不会是真的。意思可能是“OR”而不是“AND”。在我下面写的公式中,这意味着多了一个WHEN...THEN... 分支。

LAG(DATE_FLAG) OVER (ORDER BY DATE) 
       + CASE LAG(DATE_FLAG) OVER (ORDER BY DATE ) WHEN 1 THEN  1
                                                   WHEN 0 THEN -1
                                                   ELSE         0  END AS DATE_STEP

进一步编辑:再看一遍,好像flag为1、0或-1的时候就必须加1,否则加0... CASE 表达式”而不是像我一样的“搜索的 CASE 表达式”。比如:

LAG(...) ...
   + CASE WHEN LAG(...) ... IN (-1, 0, 1) THEN 1
          ELSE                                 0 END AS DATE_STEP

【讨论】:

【参考方案2】:

这样试试

CREATE VIEW GS_Date AS
SELECT DATE_DATE,
       DATE_FLAG,
       CASE
         WHEN LAG(DATE_FLAG) OVER(ORDER BY DATE_DATE) = '1' THEN
          (LAG(DATE_FLAG) OVER(ORDER BY DATE_DATE)) + '1'
         WHEN LAG(DATE_FLAG) OVER(ORDER BY DATE_DATE) = '0'   AND LAG(DATE_FLAG)  OVER(ORDER BY DATE_DATE) = '-1' THEN
          (LAG(DATE_FLAG) OVER(ORDER BY DATE_DATE)) + '1'
         ELSE
          LAG(DATE_FLAG) OVER(ORDER BY DATE_DATE)
       END AS DATE_STEP
  FROM DATE_GROUP

【讨论】:

不要将'1'之类的字符串添加到数字中!如果 OP 这样做了,并且您正在尝试帮助他们,那么即使这不是他们遇到错误的原因,也不难识别和指出。【参考方案3】:

因此您不必一直编写LAG( ... ) OVER ( ... ) 语句,在子查询中获取LAG 值,然后在外部查询中使用CASEDECODE

CREATE VIEW GS_Date AS
SELECT  DATE_DATE,
        DATE_FLAG,
        DECODE(
          DATE_STEP,
          1, 2,
          0, 1,
          -1, 0,
          DATE_STEP
        ) AS DATE_STEP
FROM    (
  SELECT  DATE_DATE, 
          DATE_FLAG,
          LAG ( DATE_FLAG )  OVER ( ORDER BY DATE_DATE ) AS DATE_STEP
  FROM    DATE_GROUP
)'

另外,你的第二个WHEN 子句永远不会是真的:

WHEN LAG ( DATE_FLAG ) OVER ( ORDER BY DATE_DATE ) = '0'
AND  LAG ( DATE_FLAG ) OVER ( ORDER BY DATE_DATE ) = '-1'
THEN ...

因为值不能同时是-10。我假设您打算使用 OR 而不是 AND

【讨论】:

以上是关于Oracle SQL LAG 函数的主要内容,如果未能解决你的问题,请参考以下文章

Oracle分析函数之Lag和Lead()使用

Hive分析函数LAG和LEAD详解

Oracle ---- 窗口函数

MYSQL lag() 和lead()函数使用介绍

Oracle 中的 LAG 函数

oracle lag与lead分析函数简介