依靠“假”列获取正确的记录

问题描述 投票:0回答:2
   SELECT * FROM (
     SELECT soi.value, srv.osp_id, soi.stya_id, eoax.estpt_id, eoax.discount, int_sero.id AS sero_id, 2 as attr_number 
     FROM srv_obj_attr_intermediate soi
     JOIN estpt_objt_attr_xref eoax ON eoax.interest_rate = 1
     JOIN attribute_types attl ON attl.id = eoax.attr_id
     JOIN object_attribute_type_links oatl ON oatl.attr_id = attl.id
     JOIN service_type_attributes sta ON sta.objt_attr_id = oatl.id
     JOIN service_objects int_sero ON int_sero.id = soi.sero_id
     JOIN services srv ON srv.id = int_sero.srv_id
     JOIN order_event_types oet ON oet.code = 'CALC_INTERMEDIATE_ESTP'
     WHERE eoax.ordet_id = oet.id AND eoax.objt_attr_id = sta.objt_attr_id
        AND soi.stya_id = sta.id AND soi.value = 1

     UNION

    SELECT soa.value, srv.osp_id, soa.stya_id, eoax.estpt_id, eoax.discount, int_sero.id AS sero_id, 1 as attr_number
    FROM srv_obj_attributes soa
    JOIN estpt_objt_attr_xref eoax ON eoax.interest_rate = 1
    JOIN attribute_types attl ON attl.id = eoax.attr_id
    JOIN object_attribute_type_links oatl ON oatl.attr_id = attl.id
    JOIN service_type_attributes sta ON sta.objt_attr_id = oatl.id
    --LEFT JOIN srv_obj_attr_intermediate soi ON soi.stya_id = sta.id
          --AND soi.value = 1
    JOIN service_objects int_sero ON int_sero.id = soa.sero_id
    JOIN services srv ON srv.id = int_sero.srv_id
    JOIN order_event_types oet ON oet.code = 'CALC_INITIAL_ESTP'
    WHERE eoax.ordet_id = oet.id AND eoax.objt_attr_id = sta.objt_attr_id
      AND soa.stya_id = sta.id AND soa.value = 1 --AND soi.value IS NULL
  )
) intrate ON intrate.estpt_id = estpt.id 
 AND intrate.sero_id = esero.sero_id 
 AND intrate.osp_id = srv.osp_id --This parameters are served. For this example we replaced srv.osp_id to 619771

此选择向我返回此记录

|VALUE                                  |OSP_ID       |STYA_ID      |ESTPT_ID                               |DISCOUNT                               |SERO_ID      |ATTR_NUMBER                            |
|---------------------------------------|-------------|-------------|---------------------------------------|---------------------------------------|-------------|---------------------------------------|
|1                                      |619771       |34659        |1812                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |1812                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |1916                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |1916                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |1987                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |1987                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |2027                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |2027                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |2028                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |2028                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |2029                                   |30                                     |3933326      |1                                      |
|1                                      |619771       |34659        |2029                                   |30                                     |3933327      |1                                      |
|1                                      |619771       |34659        |1812                                   |40                                     |3933327      |2                                      |
|1                                      |619771       |34659        |1916                                   |40                                     |3933327      |2                                      |
|1                                      |619771       |34659        |1987                                   |40                                     |3933327      |2                                      |
|1                                      |619771       |34659        |2027                                   |40                                     |3933327      |2                                      |
|1                                      |619771       |34659        |2028                                   |40                                     |3933327      |2                                      |
|1                                      |619771       |34659        |2029                                   |40                                     |3933327      |2                                      |

我需要在每个选择上添加校验,并具有自己的attr_number。基于此列,我需要返回记录。

如果用exists记录attr_number = 1,那么我应该只获取那些记录。

如果用do not exists记录attr_number = 1,那么我应该仅在attr_number = 2处获得记录。

我正试着解决我的问题,您可以看到推荐的行(left joinsoi.value IS NULL在哪里),但是它不能像我描述的那样工作。他不检查记录是否存在。

是,我们应该使用union删除重复的行。

此选择在left outer join中使用。

sql oracle select oracle10g greatest-n-per-group
2个回答
0
投票
您可以使用rank()过滤结果集:

select * from ( select t.*, rank() over( partition by osp_id, stya_id, espt_id, sero_id order by attr_number desc ) rn from ( -- your big `unioon` query ) t ) t where rn = 1

由于您没有确切说出哪些列定义了组,所以我对partition进行了假设。


[您标记了Oracle 10g的问题。但是请注意,如果要使用Oracle 12c,则使用行限制子句会更简单:

select t.* from ( -- your big `unioon` query ) t order by rank() over( partition by osp_id, stya_id, espt_id, sero_id order by attr_number desc ) fetch first 1 rows with ties


0
投票
您可以如下使用analytical function

select * from ( select t.*, Min(attr_number) over( partition by value, stya_id, espt_id) as min_a from ( -- your `union` query ) t ) t where attr_number = min_a

干杯!
© www.soinside.com 2019 - 2024. All rights reserved.