如何根据选择的列显示正确的记录
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
。基于此列,我需要返回记录。
如果记录exists
和attr_number = 2
,那么我应该只获取那些记录。
如果记录do not exists
和attr_number = 2
,那么我应该只获得attr_number = 1
的记录。
我试图解决我的问题,你可以看到推荐的行(left join
和 soi.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 函数,然后将intrate
与srv
、estpt
、esero
等进行左外连接吗?更新了我的演示以包含另一个示例
是的,它出现在我的选择中,然后我在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));
【讨论】:
以上是关于如何根据选择的列显示正确的记录的主要内容,如果未能解决你的问题,请参考以下文章
从表中选择不同的记录并执行重复行的列总和(托盘、总和)。并显示重复的行一次[关闭]