如何根据选择的列显示正确的记录

Posted

技术标签:

【中文标题】如何根据选择的列显示正确的记录【英文标题】:How to show correct records based on column from select 【发布时间】:2020-03-02 18:35:22 【问题描述】:
|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。基于此列,我需要返回记录。

如果记录existsattr_number = 2,那么我应该只获取那些记录。

如果记录do not existsattr_number = 2,那么我应该只获得attr_number = 1 的记录。

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

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

此选择用于left outer join

``

【问题讨论】:

这不是一个完整的查询——你没有外部的 select 语句或 from 行 查询未显示对 attr_number 的任何引用。请发布完整的查询 对不起,我忘了在这里添加它们。现在一切都解决了。 left outer join 也是一个信息点。通常,此选择会返回此数据。 prntscr.com/rahdvn 【参考方案1】:

好的,现在你编辑了我理解的问题......这是我将如何使用 CTE 来做的

WITH att2 AS
(
  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
), att1 AS
(
  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
), base AS
(
  SELECT estpt_id, sero_id, osp_id,
         COALESCE(att1,att2) as source
  FROM (
    SELECT estpt_id, sero_id, osp_id, 1 AS att1, null as att2
    FROM att1
    GROUP BY estpt_id, sero_id, osp_id

    UNION 

    SELECT estpt_id, sero_id, osp_id, null AS att1, 2 AS att2
    FROM att1
    GROUP BY estpt_id, sero_id, osp_id
  )
)
SELECT 
   COALESCE(att1.value,att2.value) as value,
   base.osp_id,
   COALESCE(att1.stya_id,att2.stya_id) as stya_id,
   base.estpt_id, 
   COALESCE(att1.discount,att2.discount) as discount,
   eoax.discount, 
   base.sero_id 
FROM base
LEFT JOIN att1 ON base.estpt_id = att1.estpt_id and base.sero_id = att1.sero_id and base.osp_id and att1.osp_id and source = 1
LEFT JOIN att2 ON base.estpt_id = att2.estpt_id and base.sero_id = att2.sero_id and base.osp_id and att2.osp_id and source = 2

【讨论】:

谢谢!这一切都应该在左外连接内使用吗?在这里加入什么? :) 我不知道您所说的左外连接是什么意思——您拒绝显示该代码,所以我无法为您提供帮助。 @Viktor——不管它是什么 CTE 在 JOIN 中都不起作用,所以我必须查看该代码来帮助你。【参考方案2】:

如果存在 attr_number = 2 的记录,那么我应该只获取那些记录。 如果 attr_number = 2 的记录不存在,那么我应该只获取 attr_number = 1 的记录。

对从左外连接获取的记录使用RANK 可以解决这个问题吗?

简单演示here。

【讨论】:

不完全。我不能出去left outer join,所以我需要在里面工作。因此,您的解决方案选项将不起作用,呵呵。我也有一个使用排名的想法,但是我需要在 select 中通过osp_id 查找记录,女巫不会工作,因为srv.osp_id 只存在于外面。 对不起,我帮不上忙,但不确定我是否完全理解 :) 根据您的图像,osp_id 出现在选择中(从技术上讲,这是您调用的子查询 intrate) .难道不是在intrate 内应用rank 函数,然后将intratesrvestptesero 等进行左外连接吗?更新了我的演示以包含另一个示例 是的,它出现在我的选择中,然后我在intrate 中调用它并进行比较。这应该保持原样。我会检查你的第二个解决方案。谢谢。 还是不行。我不能出去,intrate后面应该没有where声明。你忘了一件事,attr_number 是虚构的列,所以我不能只做 9 行并从任何列中选择该值。【参考方案3】:

请看看你是否可以使用这个过滤器

with test  as
   (select 1 id, 'ABC attr 1' description, 1 attr_number from dual union all
select 2 id, 'DEF attr 1' description, 1 attr_number from dual union all
select 2 id, 'DEF attr 2' description, 2 attr_number from dual union all
select 2 id, 'DEF attr 3' description, 3 attr_number from dual union all
select 3 id, 'GHI attr 3' description, 3 attr_number from dual
   )
   select *
   from test t1
   where attr_number = 2
   or ( attr_number = 1 and not exists (select 1 from test t2 where t2.attr_number = 2 and t1.id = t2.id));

【讨论】:

以上是关于如何根据选择的列显示正确的记录的主要内容,如果未能解决你的问题,请参考以下文章

如何根据作为输入的列表正确排序 QTreeView 中的列

从表中选择不同的记录并执行重复行的列总和(托盘、总和)。并显示重复的行一次[关闭]

根据正确选择的单选按钮显示下拉菜单

如何在 XSLT 表中显示正确的内容

如何以正确的格式以科学记数法显示 PySpark 数据框中的列

根据另一个表中的条件显示表中的列