2017-07-04 81 views
1
TABLE : **PROFILE** 
RUN_ID| Type | code | gender | vacId 

1  | A | biz | M  | 110 
2  | A | pro | M  | 113 
3  | A | tot | F  | 114 

必需根據所輸入的返回vacId,如果我輸入,如果代碼+型組合不存在,則僅返回vacId其等於給定類型如果子集組合返回空結果,則查詢獲取超集?

  1. TYPE = A和代碼= BIZ AND性別= M,那麼它應該返回110
  2. TYPE = A,然後CODE = SYS應返回110 & 113,114有這麼回超A的數據

沒有A + SYS組合,我怎麼能寫查詢這應該工作pgsql和oracle現在。

有沒有一種方法,我可以做到這一點使用COALESCE

回答

1

可以使用條件where條款,如($用於參數):

select p.* 
from profile p 
where case 
    when exists (
     select 1 
     from profile 
     where type = $type and code = $code and gender = $gender 
     ) 
    then type = $type and code = $code and gender = $gender 
    else type = $type 
    end; 

更新。

另一種解決方案可能是得到一個JSON對象的結果,是什麼使您使用coalesce()

select coalesce(
    (select jsonb_agg(to_jsonb(p)) 
    from profile p 
    where type = $type and code = $code and gender = $gender), 
    (select jsonb_agg(to_jsonb(p)) 
    from profile p 
    where type = $type) 
); 
+0

這會不止一次地打到數據庫?此查詢中的任何性能問題?可以在這裏添加多個案例嗎? – user630209

+0

子查詢涉及額外的掃描,但它比主要的掃描便宜,特別是當正在使用適當的索引時。您可以在'case'語句中使用多個子查詢,只需在'else'之前添加'when ... then ...'。 – klin

+0

只是一個額外的查詢。爲了降低性能風險,返回所有json數據並在View(前端)上過濾它會更好嗎? – user630209

0

你可以寫這樣的查詢。首先根據類型和代碼計算計數並使用該信息來獲得實際結果。在這裏你不需要在查詢中的任何地方使用exists子句。

with get_count_bytypecode as (select type,code,count(*) as codetypecount 
from PROFILE where code = 'biz' and type = 'A' 
group by type, code) 
select * from PROFILE t join get_count_bytypecode gc on 
gc.type = t.type 
and case when codetypecount > 0 then gc.code = t.code else 1=1 end