使用带内联选择语句的子查询将INNER JOIN添加到查询中

时间:2016-06-02 21:07:48

标签: sql oracle join subquery

我有以下可用的SQL:

Select TRADING_DWKEY,
       M_SM_USER_CODE,
       FIRST_TRADE,
       'New Footprint' Status,
       Null Q4Vol,
       CQVol 
  From (Select A.TRADING_DWKEY||A.RM_SM_USER_CODE,
               A.TRADING_DWKEY,
               A.RM_SM_USER_CODE,
               B.FIRST_TRADE, SUM(A.RISK_AMOUNT_ADJ)/1000000 CQVol
          from FACT_TRADE_ROLLUP A,
               (SELECT TRADING_DWKEY,
                       MIN(FIRST_TRADE_DATE) FIRST_TRADE 
                  FROM ACCOUNT_FIRST_LAST_TRADE_DATES
                  Having MIN(FIRST_TRADE_DATE) >= to_char(trunc((sysdate-1),'Y'),'dd-Mon-yy')
                  GROUP BY TRADING_DWKEY) B
          WHERE A.DATE_KEY>='01-Jan-16' AND
                ((A.PRODUCT_DWKEY IN ('RT') AND  A.Account_Type='Customer') OR
                  A.PRODUCT_DWKEY IN('OB','BS','MM')) AND
                A.Role = 'SM' AND
                A.TRADING_DWKEY = B.TRADING_DWKEY
          GROUP BY A.TRADING_DWKEY||A.RM_SM_USER_CODE,
                   A.TRADING_DWKEY,
                   A.RM_SM_USER_CODE,
                   B.FIRST_TRADE
          HAVING SUM(A.RISK_AMOUNT_ADJ)>=20000000) NewFP;

当我尝试将INNER JOIN添加到子查询(以提取名称而不是代码)时,我得到一个错误,即A.RM_SM_USER_CODE不是我写INNER JOIN的行上的有效标识符。但是,我肯定此字段存在于FACT_TRADE_ROLLUP表中。我怀疑这个错误与我放置INNER JOIN的地方有关,但无法弄清楚。

这是完全修改过的SQL(但即使我只是在没有实际修改列的情况下放入INNER JOIN语句,我也会收到错误。

Select TRADING_DWKEY,
       RM_SM_NAME,
       FIRST_TRADE,
       'New Footprint' Status,
       Null Q4Vol,
       CQVol 
  From (Select A.TRADING_DWKEY||A.RM_SM_USER_CODE,
               A.TRADING_DWKEY,
               q.RM_SM_NAME,
               B.FIRST_TRADE,
               SUM(A.RISK_AMOUNT_ADJ)/1000000 CQVol 
          from FACT_TRADE_ROLLUP A,
               (SELECT TRADING_DWKEY, MIN(FIRST_TRADE_DATE) FIRST_TRADE  
                  FROM ACCOUNT_FIRST_LAST_TRADE_DATES
                  Having MIN(FIRST_TRADE_DATE)>=to_char(trunc((sysdate-1),'Y'),'dd-Mon-yy')
                  GROUP BY TRADING_DWKEY) B
  --- error thrown on this line, specifying it at the end
          INNER JOIN REF_RM_SM_REGION q
            on q.RM_SM_USER_CODE = A.RM_SM_USER_CODE
          WHERE A.DATE_KEY>='01-Jan-16' AND
                ((A.PRODUCT_DWKEY IN('RT') AND A.Account_Type='Customer') OR 
                  A.PRODUCT_DWKEY IN('OB','BS','MM')) AND
                A.Role = 'SM' AND
                A.TRADING_DWKEY = B.TRADING_DWKEY
          GROUP BY A.TRADING_DWKEY||A.RM_SM_USER_CODE,
                   A.TRADING_DWKEY,
                   q.RM_SM_NAME,
                   B.FIRST_TRADE
          HAVING SUM(A.RISK_AMOUNT_ADJ)>=20000000) NewFP;

2 个答案:

答案 0 :(得分:3)

没有任何定义表的DDL语句很难测试,但是:

  1. 您正在使用字符串比较日期 - Oracle可能使用NLS_DATE_FORMAT会话参数(希望DD-MON-YY)的值进行隐式转换回日期,但如果这种情况发生了变化,那么它将打破查询(并且查询将不会更改,因此调试将是一件痛苦的事)。停止使用字符串作为日期并使用日期文字 - 即DATE '2016-01-01'
  2. 您在HAVING子句之前有第一个GROUP BY子句 - 交换它们。
  3. 您还混合使用旧版逗号连接和ANSI连接 - 将逗号连接替换为INNER JOIN,并将连接条件移出WHERE子句。
  4. A.TRADING_DWKEY||A.RM_SM_USER_CODE分组效率低下。您已将A.TRADING_DWKEY作为GROUP BY个术语之一,因此请勿连接字符串,只包含GROUP BY子句中的其他列。
  5. 类似的东西:

    Select TRADING_DWKEY,
           RM_SM_NAME,
           FIRST_TRADE,
           'New Footprint' Status,
           Null Q4Vol,
           CQVol 
    From (
      Select A.TRADING_DWKEY,
             q.RM_SM_NAME,
             B.FIRST_TRADE,
             SUM(A.RISK_AMOUNT_ADJ)/1000000 CQVol 
      from   FACT_TRADE_ROLLUP A
             INNER JOIN
             ( SELECT   TRADING_DWKEY,
                        MIN(FIRST_TRADE_DATE) FIRST_TRADE  
               FROM     ACCOUNT_FIRST_LAST_TRADE_DATES
               GROUP BY TRADING_DWKEY
               HAVING   MIN(FIRST_TRADE_DATE)>= trunc(sysdate-1,'Y')
             ) B
             ON ( A.TRADING_DWKEY=B.TRADING_DWKEY )
             INNER JOIN REF_RM_SM_REGION q
             ON ( q.RM_SM_USER_CODE = A.RM_SM_USER_CODE )
      WHERE A.DATE_KEY >= DATE '2016-01-01'
      AND   ( (    A.PRODUCT_DWKEY IN('RT')
               AND A.Account_Type='Customer'
              )
            OR A.PRODUCT_DWKEY IN('OB','BS','MM')
            )
      AND   A.Role = 'SM' 
      GROUP BY A.RM_SM_USER_CODE,
               A.TRADING_DWKEY,
               q.RM_SM_NAME,
               B.FIRST_TRADE
      HAVING SUM(A.RISK_AMOUNT_ADJ)>=20000000
    );
    

答案 1 :(得分:2)

Select TRADING_DWKEY, RM_SM_NAME, FIRST_TRADE, 'New Footprint' Status, Null Q4Vol, CQVol 
From (
    Select
        A.TRADING_DWKEY || A.RM_SM_USER_CODE, /* No name. So is this even used? */
        A.TRADING_DWKEY,
        q.RM_SM_NAME, B.FIRST_TRADE, SUM(A.RISK_AMOUNT_ADJ) / 1000000 CQVol 
    from FACT_TRADE_ROLLUP A INNER JOIN /* <--- Changed here... */
        (
        SELECT TRADING_DWKEY, MIN(FIRST_TRADE_DATE) FIRST_TRADE  
        FROM ACCOUNT_FIRST_LAST_TRADE_DATES
        Having MIN(FIRST_TRADE_DATE)>=to_char(trunc((sysdate-1),'Y'),'dd-Mon-yy')
        GROUP BY TRADING_DWKEY /* Very odd it ran with this after HAVING */
        ) B
            ON B.TRADING_DWKEY = A.TRADING_DWKEY /* <--- ...and here */
        INNER JOIN REF_RM_SM_REGION q on q.RM_SM_USER_CODE = A.RM_SM_USER_CODE
    WHERE
        A.DATE_KEY>='01-Jan-16'
            AND (A.PRODUCT_DWKEY IN('RT') AND A.Account_Type='Customer')
                OR A.PRODUCT_DWKEY IN('OB','BS','MM'))
            AND A.Role = 'SM'
  /* removed line that was here */ 
  GROUP BY
      A.TRADING_DWKEY||A.RM_SM_USER_CODE, A.TRADING_DWKEY,
      q.RM_SM_NAME, B.FIRST_TRADE
  HAVING SUM(A.RISK_AMOUNT_ADJ) > =20000000
) NewFP;

我尽了最小的努力来清理它。希望我没有在这个过程中打破它。如上所述,可能是两种类型的连接语法的混合导致了错误。