以下是java中的查询
SELECT achieve_STATUS_CD
FROM achievemnt
WHERE env_id = '?' AND ROWNUM = 1
ORDER BY achive_status_dt
需要返回值' Y'基于另外两个表的注册,提供以下条件
对于其余所有条件,它应该从原始查询返回值(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;
答案 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表
您可以释放条件
TMP子查询上的AND R.env_ID =&#39;?&#39;
。 在这种情况下,查询是基于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;