我的表格结构如下:
ID STATUS_1 STATUS_2 VERSION
1 Success Disabled 5
2 Disabled In_Progress 3
3 Disabled Disabled 4
我需要返回所有行
Success
或In_Progress
Success
或In_Progress
状态的STATUS_1或STATUS_2,则应返回具有最低VERSION值的行。在当前表中,返回的行将是:
1 Success Disabled 5
2 Disabled In_Progress 3
所以如果我的表看起来像这样:
ID STATUS_1 STATUS_2 VERSION
1 -- Disabled 5
2 Disabled -- 3
3 Disabled Disabled 4
返回的唯一行应为
2 Disabled -- 3
因为它的版本最低(3)。
这可以通过IF
子句中的WHERE
语句完成吗?
答案 0 :(得分:1)
以下查询似乎是您想要的。首先,我使用CTE计算具有Success
或In_progress
的记录数。稍后,我们可以使用此计数来确定是否需要返回具有最低版本的单行,或者所有匹配的行。
我在查找找到最低版本记录的查询和返回所有匹配行的第二个查询之间取UNION
。诀窍是,UNION
的前半部分中的单行仅在匹配计数为零时才会保留。否则,它将被删除,UNION
的这部分将不对结果集做出任何贡献。请注意,如果我们确实保留了单个最低版本的记录,那么根据定义,查询的后半部分本身不会返回任何内容,仍然会在结果集中留下我们的单个记录。
WITH cte AS (
SELECT COUNT(*) cnt
FROM yourTable
WHERE
STATUS_1 IN ('Success', 'In_Progress') OR
STATUS_2 IN ('Success', 'In_Progress')
)
SELECT t.ID, t.STATUS_1, t.STATUS_2, t.VERSION
FROM
(
SELECT ID, STATUS_1, STATUS_2, VERSION,
ROW_NUMBER() OVER (ORDER BY VERSION) rn
FROM yourTable
) t
WHERE
t.rn = 1 AND
(SELECT cnt FROM cte) = 0
UNION ALL
SELECT ID, STATUS_1, STATUS_2, VERSION
FROM yourTable
WHERE
STATUS_1 IN ('Success', 'In_Progress') OR
STATUS_2 IN ('Success', 'In_Progress')
以下是一个演示,您可以在其中探索此查询:
请注意,我在演示中使用了SQL Server,因为设置Oracle演示很麻烦,但是查询应该在很少或没有修改的情况下在Oracle上运行。
答案 1 :(得分:0)
您可以使用CASE
语句,它的作用类似于IF-THEN-ELSE
答案 2 :(得分:0)
请尝试以下查询,并告诉我它是否有效
select id,STATUS_1,status_2,version from status
where status_1 in ('In progress','Success')
and Status_2 in ('In progress','Success')
union all
select id,status_1,status_2,version from
(
select id,status_1,status_2,version,
row_number() over(order by version) as rn
from status
where status_1 not in ('In progress','Success') or
status_2 not in ('In progress','Success')
)a
where a.rn=1
答案 3 :(得分:0)
对于if else,你可以使用“case when ......”,“coalesce()”或“decode()”。以下示例使用“case when ......”。
create table states (
ID number,
STATUS_1 varchar2(50),
STATUS_2 varchar2(50),
VERSION number
);
insert into states values (1, 'Success', 'Disabled', 5);
insert into states values (2, 'Disabled', 'In_Progress', 3);
insert into states values (3, 'Disabled', 'Disabled', 4);
select t.*
from ( select s.*,
rank() over (order by version asc) as rnk,
count( case
when s.status_1 = 'Success' then 1
when s.status_1 = 'In_Progress' then 1
when s.status_2 = 'Success' then 1
when s.status_2 = 'In_Progress' then 1
else null
end
) over () as cnt
from states s ) t
where (t.rnk = 1 and t.cnt = 0)
or (t.status_1 in ('Success', 'In_Progress'))
or (t.status_2 in ('Success', 'In_Progress'))
玩得开心