2017-07-04 80 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