如何将值从主选择查询传递到子查询

时间:2017-07-21 04:39:42

标签: sql sql-server database oracle subquery

    SELECT c.serno,
       NVL (
          (SELECT t1.newvalue
             FROM (  SELECT newvalue
                       FROM applog
                      WHERE     TABNAME = 'cextension'
                            AND rowserno = c.serno -- ERROR
                            AND colname = 'A11103'
                   ORDER BY datetimestamp DESC) t1
            WHERE ROWNUM = 1),
          (SELECT t2.newvalue
             FROM (  SELECT newvalue
                       FROM archapplog
                      WHERE     TABNAME = 'cextension'
                            AND rowserno = c.serno -- ERROR
                            AND colname = 'A11103'
                   ORDER BY datetimestamp DESC) t2
            WHERE ROWNUM = 1)) AS "JoinCreditShieldProgram"
  FROM caccounts c
你好!我正在使用oracle DB并尝试运行此查询,但它在子查询中的“c.serno”上给出了标识符错误。请帮我解决这个错误?感谢。

4 个答案:

答案 0 :(得分:0)

您必须使用左外连接而不是纯子查询,如图所示。

SELECT c.serno, NVL(t1.newvalue,t2.newvalue) AS "JoinCreditShieldProgram" FROM
caccounts c LEFT OUTER JOIN
      (SELECT newvalue,rowserno
         FROM (  SELECT newvalue,rowserno
                   FROM applog
                  WHERE     TABNAME = 'cextension'
                        AND colname = 'A11103'
               ORDER BY datetimestamp DESC) 
        WHERE ROWNUM = 1) t1 ON  t1.rowserno = c.serno
        LEFT  OUTER JOIN 
      (SELECT newvalue,rowserno
         FROM (  SELECT newvalue,rowserno
                   FROM archapplog
                  WHERE     TABNAME = 'cextension'
                        AND colname = 'A11103'
               ORDER BY datetimestamp DESC) 
        WHERE ROWNUM = 1) t2   ON t2.rowserno = c.serno;

答案 1 :(得分:0)

可能更易于阅读和理解的查询(尽管您需要测试性能)是:

SELECT c.serno,
     NVL(t1.newvalue, t2.newvalue) AS "JoinCreditShieldProgram"
FROM   caccounts c
       LEFT OUTER JOIN (SELECT rowserno,
                               newvalue,
                               row_number() OVER (PARTITION BY rowserno ORDER BY datetimestamp DESC) rn
                        FROM   applog
                        WHERE  tabname = 'cextension'
                        AND    colname = 'A11103') t1 ON c.serno = t1.rowserno AND t1.rn = 1
       LEFT OUTER JOIN (SELECT rowserno,
                               newvalue,
                               row_number() OVER (PARTITION BY rowserno ORDER BY datetimestamp DESC) rn
                        FROM   archapplog
                        WHERE  tabname = 'cextension'
                        AND    colname = 'A11103') t2 ON c.serno = t2.rowserno AND t2.rn = 1;

答案 2 :(得分:0)

Personnaly,如果我必须从两个单独的表中获取最后一个值,然后必须在它们之间进行NVL,我更喜欢使用LAST_VALUE Analytic函数。

SELECT DISTINCT
  c.serno, 
  LAST_VALUE(logs.newvalue) over 
    ( partition by logs.rowserno order by logs.datetimestamp 
      ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING ) AS "JoinCreditShieldProgram"
FROM
  caccounts c
LEFT JOIN
  (
    SELECT rowserno, newvalue, datetimestamp 
    FROM applog
    WHERE tabname = 'cextension' AND colname = 'A11103'
    UNION
    SELECT rowserno, newvalue, datetimestamp 
    FROM archapplog
    WHERE tabname = 'cextension' AND colname = 'A11103'
  ) logs
ON
  c.serno = logs.rowserno;

答案 3 :(得分:-1)

I am not sure why you are using inline view in your query statement.
It is not required you can directly put "rownum" limit and even in more simple way, like below-

SELECT * 
FROM   (SELECT c.serno, 
               Nvl (a.newvalue, b.newvalue) AS "JoinCreditShieldProgram" 
        FROM   caccounts c 
               LEFT OUTER JOIN applog a 
                            ON c.serno = a.rowserno 
               LEFT OUTER JOIN archapplog b 
                            ON c.serno = b.rowserno 
        WHERE  a.tabname = 'cextension' 
               AND a.colname = 'A11103' 
               AND b.tabname = 'cextension' 
               AND b.colname = 'A11103' 
        ORDER  BY a.datetimestamp DESC, 
                  b.datetimestamp DESC) 
WHERE  rownum = 1;