【问题标题】:Oracle SQL LAG FunctionOracle SQL LAG 函数
【发布时间】: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

标签: sql oracle lag window-functions


【解决方案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 值,然后在外部查询中使用CASE 或DECODE:

    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 ...
    

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

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 2016-03-13
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多