结合CONCAT和LAG函数

时间:2016-07-07 10:18:32

标签: sql oracle

首先,这涉及到如何成功解决Oracle SQL- Flag records based on record's date vs history的帖子。我决定开设一个新主题有两个原因:

  1. 这是一个新问题(虽然它与前一个问题有关)。
  2. 有人可能会发现原帖中的解决方案很有用,所以我不想让它改变。
  3. 我目前正在运行以下查询(由@Mottor提供):

    SELECT
    "REGION"
    , "COUNTRY"
    , "IDNum"
    , "CUSTOMER"
    , "BUSSINESS"
    , "FISCALYEARMONTH"
    , "FISCALYEAR"
    , SUM("VALUE") 
    , MAX(CASE WHEN to_date(prev_fym,'YYYYMM')  >= ADD_MONTHS (to_date("FISCALYEARMONTH",'YYYYMM'), -24) THEN 'Existing' 
               ELSE 'New ' END) "HISTORICAL_PURCHASE_FLAG"
    FROM
    (
        SELECT
        T1."REGION"
        , T1."COUNTRY"
        , T1."IDNum"
        , T1."CUSTOMER"
        , T2."BUSSINESS"
        , T3."FISCALYEARMONTH"
        , T3."FISCALYEAR"
        , T4."VALUE"
        , LAG ("FISCALYEARMONTH", 1) OVER (PARTITION BY T1."IDNum" ORDER BY T3."FISCALYEARMONTH" DESC) prev_fym 
        FROM
        "DATABASE"."SALES" T4
        , "DATABASE"."CUSTOMER" T1
        , "DATABASE"."PRODUCT" T2
        , "DATABASE"."TIME" T3
        WHERE
        T4."CUSTOMERID" = T1."CUSTOMERID"
        AND T4."PRODUCTID" = T2."PRODUCTID"
        AND T4."DATEID" = T3."DATEID"
        AND T1."COUNTRY" IN ('ENGLAND', 'France')
        AND T3."FISCALYEAR" IN ('2014','2015','2016')
    )
    WHERE "FISCALYEAR" IN ('2016')
    GROUP BY
    "REGION"
    , "COUNTRY"
    , "IDNum"
    , "CUSTOMER"
    , "BUSSINESS"
    , "FISCALYEARMONTH"
    , "FISCALYEAR"
    ;
    

    因此,我获得了2016财年所有交易的清单。此外,LAG功能允许我将记录标记为'新'或者'现有',基于" IDNum"和" FISCALYEARMONTH"。我得到以下结果:

    LineNum REGION  COUNTRY IDNum   CUSTOMER            BUSSINESS       FISCALYEARMONTH FISCALYEAR  VALUE        HISTORICAL_PURCHASE_FLAG
    1       Europe  ENGLAND 255     Abraxo Cleaner Co.  Chemicals       201605           2016       34,567.00    Existing   
    2       Europe  FRANCE  123     Metal Trade         Heavy           201602           2016       12,500.00    Existing
    3       Europe  ENGLAND 255     Abraxo Cleaner Co.  Mining          201601           2016       8,400.00     New    
    

    我目前面临的问题是,单个客户实际上可以属于多个业务。如果你看一下上面的例子,你会发现Abraxo Cleaner Co.属于化学品和采矿业。

    我正在尝试创建一个名为" CUSTOMER_BUSSINESS_KEY"这将是一个串联:CONCAT(T1."IDNum",T2."BUSSINESS")

    接下来,我想修改LAG函数,如下所示:LAG ("FISCALYEARMONTH", 1) OVER (PARTITION BY "CUSTOMER_BUSSINESS_KEY" ORDER BY T3."FISCALYEARMONTH" DESC) prev_fym。这应该让我得到标记为“新”的记录。和'现有'基于新创建的列,而不是" IDNum"。

    问题是,当我运行查询时,我收到一条错误消息:

      

    ORA-00904:" CUSTOMER_BUSSINESS_KEY":无效标识符

    我的理解是SQL找不到" CUSTOMER_BUSSINESS_KEY"的表名。不幸的是,我无法找到解决方法。

1 个答案:

答案 0 :(得分:0)

您不能在同一个Select中使用别名,要么添加另一个派生表,要么使用计算:

SELECT
"REGION"
, "COUNTRY"
, "IDNum"
, "CUSTOMER"
, "BUSSINESS"
, "CUSTOMER_BUSSINESS_KEY"
, "FISCALYEARMONTH"
, "FISCALYEAR"
, SUM("VALUE") 
, MAX(CASE WHEN to_date(prev_fym,'YYYYMM')  >= ADD_MONTHS (to_date("FISCALYEARMONTH",'YYYYMM'), -24) THEN 'Existing' 
           ELSE 'New ' END) "HISTORICAL_PURCHASE_FLAG"
FROM
(
    SELECT
    T1."REGION"
    , T1."COUNTRY"
    , T1."IDNum"
    , T1."CUSTOMER"
    , T2."BUSSINESS"
    , CONCAT(T1."IDNum",T2."BUSSINESS") AS "CUSTOMER_BUSSINESS_KEY"
    , T3."FISCALYEARMONTH"
    , T3."FISCALYEAR"
    , T4."VALUE"
    , LAG ("FISCALYEARMONTH", 1)
      OVER (PARTITION BY CONCAT(T1."IDNum",T2."BUSSINESS")
            ORDER BY T3."FISCALYEARMONTH" DESC) prev_fym 
    FROM
    "DATABASE"."SALES" T4
    , "DATABASE"."CUSTOMER" T1
    , "DATABASE"."PRODUCT" T2
    , "DATABASE"."TIME" T3
    WHERE
    T4."CUSTOMERID" = T1."CUSTOMERID"
    AND T4."PRODUCTID" = T2."PRODUCTID"
    AND T4."DATEID" = T3."DATEID"
    AND T1."COUNTRY" IN ('ENGLAND', 'France')
    AND T3."FISCALYEAR" IN ('2014','2015','2016')
)
WHERE "FISCALYEAR" IN ('2016')
GROUP BY
"REGION"
, "COUNTRY"
, "IDNum"
, "CUSTOMER"
, "BUSSINESS"
, "FISCALYEARMONTH"
, "FISCALYEAR"
;

但您也可以在PARTITION中使用多个列:

SELECT
"REGION"
, "COUNTRY"
, "IDNum"
, "CUSTOMER"
, "BUSSINESS"
, "FISCALYEARMONTH"
, "FISCALYEAR"
, SUM("VALUE") 
, MAX(CASE WHEN to_date(prev_fym,'YYYYMM')  >= ADD_MONTHS (to_date("FISCALYEARMONTH",'YYYYMM'), -24) THEN 'Existing' 
           ELSE 'New ' END) "HISTORICAL_PURCHASE_FLAG"
FROM
(
    SELECT
    T1."REGION"
    , T1."COUNTRY"
    , T1."IDNum"
    , T1."CUSTOMER"
    , T2."BUSSINESS"
    , T3."FISCALYEARMONTH"
    , T3."FISCALYEAR"
    , T4."VALUE"
    , LAG ("FISCALYEARMONTH", 1)
      OVER (PARTITION BY T1."IDNum",T2."BUSSINESS"
            ORDER BY T3."FISCALYEARMONTH" DESC) prev_fym 
    FROM
    "DATABASE"."SALES" T4
    , "DATABASE"."CUSTOMER" T1
    , "DATABASE"."PRODUCT" T2
    , "DATABASE"."TIME" T3
    WHERE
    T4."CUSTOMERID" = T1."CUSTOMERID"
    AND T4."PRODUCTID" = T2."PRODUCTID"
    AND T4."DATEID" = T3."DATEID"
    AND T1."COUNTRY" IN ('ENGLAND', 'France')
    AND T3."FISCALYEAR" IN ('2014','2015','2016')
)
WHERE "FISCALYEAR" IN ('2016')
GROUP BY
"REGION"
, "COUNTRY"
, "IDNum"
, "CUSTOMER"
, "BUSSINESS"
, "FISCALYEARMONTH"
, "FISCALYEAR"
;