2017-08-09 49 views
1

我的表結構如下:IF在聲明WHERE子句 - SQL - 甲骨文

ID  STATUS_1 STATUS_2 VERSION 
1  Success Disabled  5 
2  Disabled In_Progress 3 
3  Disabled Disabled  4 

我需要回到這裏無論是

  • STATUS_1或STATUS_2要麼SuccessIn_Progress
  • 所有行
  • 如果沒有行具有帶有SuccessIn_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)。

這可以通過WHERE條款中的IF語句完成嗎?

+0

我與你的預期輸出的一部分不同意。前兩行應該與您的第一個示例數據一起返回,因爲這兩行都有「Success」或「In_progress」。 –

回答

1

下面的查詢似乎是你想要的。首先,我使用計算具有SuccessIn_progress的記錄數的CTE。稍後,我們可以使用此計數來確定是否需要返回具有最低版本的單行,或者是否返回所有匹配的行。

我在發現記錄的查詢與最低版本的查詢和返回所有匹配行的第二個查詢之間取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') 

這裏是一個演示,你可以探索這個查詢:因爲設置了Oracle演示是一種痛苦

Rextester

注意,我在演示中使用的SQL Server,但查詢應運行在Oracle上幾乎沒有修改。

0

您可以使用CASE聲明,它像IF-THEN-ELSE

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 
0

因爲如果你還能用「當......的情況下」,「COALESCE()」或「解碼()」。以下示例使用「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')) 

玩得開心