在单个oracle sql语句中返回多个值

时间:2016-11-01 20:46:38

标签: sql oracle

以下是java中的查询

SELECT achieve_STATUS_CD
FROM achievemnt
WHERE env_id = '?' AND ROWNUM = 1 
ORDER BY achive_status_dt

需要返回值' Y'基于另外两个表的注册,提供以下条件

  1. enrollment.achieve_intent =' 2'
  2. enrollment.BEGIN_DT> =                    至今 (                       05/01/2011,                       ' MM / DD / YYYY') 3.provision.RELEASE_DT< = SYSDATE
  3. 对于其余所有条件,它应该从原始查询返回值(SELECT achieve_STATUS_CD FROM achievemnt WHERE env_id ='?' AND ROWNUM = 1 ORDER BY achive_status_dt)

    achievemnt是注册的子表

    我怎么写这个逻辑?

    我已经写了下面的查询,但它在2个地方有env_id,但是我们现在无法在java中更改它,所以我需要写一个只接受env_id的查询

    WITH TMP
         AS (SELECT 'Y' AS achieve_STATUS_CD, env_id
               FROM enrollment r, provision a
              WHERE     r.prov_id = a.prov_id
                    AND r.achieve_intent = '2'
                    AND a.BEGIN_DT >=
                           TO_DATE (
                              05/01/2011,
                              'MM/DD/YYYY')
                    AND a.RELEASE_DT <= SYSDATE AND R.env_ID = '?')
    SELECT NVL (F.achieve_STATUS_CD,TMP.achieve_STATUS_CD)
    FROM TMP FULL OUTER JOIN
         (SELECT achieve_STATUS_CD
          FROM achievemnt
          WHERE env_id = '?' AND
                ROWNUM = 1
          ORDER BY achive_status_dt
         ) F
         ON TMP.env_ID = F.env_ID;
    

3 个答案:

答案 0 :(得分:0)

您的初始查询很可能不正确。此查询中的rownum = 1谓词在ORDER BY之前应用,因此您要求env_id为任意绑定值的任意行,然后对生成的单行进行排序。排序单行显然毫无意义。

SELECT achieve_STATUS_CD
  FROM achievemnt
 WHERE env_id = '?' 
   AND ROWNUM = 1 
 ORDER BY achive_status_dt

如果您想对多行进行排序并选择第一行achive_status_dt的行,您需要类似

的内容
SELECT *
  FROM (SELECT achieve_STATUS_CD
          FROM achievemnt
         WHERE env_id = '?' 
         ORDER BY achive_status_dt) a
 WHERE a.ROWNUM = 1 

但是,如果您的实际问题是第二个查询执行了您想要的操作(考虑到我刚刚提到的问题,这似乎不太可能),但您想使用单个绑定变量执行此操作,您只需添加另一个选择的CTE来自dual的绑定变量然后在任何你想要的地方引用CTE

WITH env
     AS (SELECT '?' env_id from dual)
    ,TMP
     AS (SELECT 'Y' AS achieve_STATUS_CD, env_id
           FROM enrollment r, provision a, env
          WHERE     r.prov_id = a.prov_id
                AND r.achieve_intent = '2'
                AND a.BEGIN_DT >=
                       TO_DATE (
                          05/01/2011,
                          'MM/DD/YYYY')
                AND a.RELEASE_DT <= SYSDATE 
                AND R.env_ID = env.env_ID)
SELECT NVL (F.achieve_STATUS_CD,TMP.achieve_STATUS_CD)
FROM TMP FULL OUTER JOIN
     (SELECT achieve_STATUS_CD
      FROM achievemnt
           join env
             on achievement.env_id = env.env_id
      WHERE ROWNUM = 1
      ORDER BY achive_status_dt
     ) F
     ON TMP.env_ID = F.env_ID;

答案 1 :(得分:0)

假设:

1- rownum的问题是正确的(我同意贾斯汀)

2-始终填充了achievemnt表

您可以释放条件

  

AND R.env_ID =&#39;?&#39;

TMP子查询上的

。 在这种情况下,查询是基于env_id的LEFT外连接应该足够了。

所以完整的查询应该是这样的(我没有一个sql控制台来测试它)

<script src="https://maps.googleapis.com/maps/api/js"></script>
<label>Boys/Girls?</label>
<select id="delivery">
  <option value="">--Select--</option>
  <option value="Boys">Boys</option>
  <option value="Girls">Girls</option>
</select>
<div id="googft-mapCanvas">

</div>

请注意,我将NVL字段反转:如果TMP.achieve_STATUS_CD不为空,即如果存在一行,则应该采用该值(始终为Y),否则为来自achievemnt的值。

如果assuntion 2不成立,则可以反转外连接中的2个子查询。

如果您需要具有最早日期的eventmnt记录,F可能会变成这样的

WITH TMP
 AS (SELECT 'Y' AS achieve_STATUS_CD, env_id
       FROM enrollment r, provision a
      WHERE     r.prov_id = a.prov_id
            AND r.achieve_intent = '2'
            AND a.BEGIN_DT >=
                   TO_DATE (
                      05/01/2011,
                      'MM/DD/YYYY')
            AND a.RELEASE_DT <= SYSDATE ),
F 
AS (SELECT TMP.achieve_STATUS_CD
  FROM achievemnt
  WHERE env_id = '?' AND
        ROWNUM = 1
  ORDER BY achive_status_dt)
SELECT NVL (TMP.achieve_STATUS_CD, F.achieve_STATUS_CD)
FROM F LEFT OUTER JOIN TMP
 ON  F.env_ID=TMP.env_ID;

答案 2 :(得分:0)

这就是我理解你的问题的方式(我可能完全错了):如果env_id节目中至少有一个与您的条件匹配的注册/提供对,则显示第一个成就它的状态。

select 
  case when exists
  (
    select *
    from enrollment e
    join provision p on p.prov_id = e.prov_id
    where e.achieve_intent = '2'
    and p.begin_dt >= date '2011-05-01'
    and p.release_dt <= sysdate 
    and e.env_id = :env_id
  ) then 'Y'
  else
  (
    select max(achieve_status_cd) keep (dense_rank first order by achive_status_dt)
    from achievement
    where env_id = :env_id
  ) as status
from dual;

如果您想在查询中只输入一次:env_id,请稍微更改为:

select 
  case when exists
  (
    select ...
    and e.env_id = main.env_id
  ) then 'Y'
  else
  (
    select ...
    where env_id = main.env_id
  ) as status
from (select :env_id as env_id from dual) main;
相关问题