[英]Oracle SQL - Making a one to many join one to one based on logic
抱歉,我的标题很宽泛,我很难想出一种简短的方式来描述我要做什么。 我有两个要联接的表(下面的示例),但是在一定条件下。
主表有一个名为“ DateVal”的字段,第二个表有一个名为“ Day”的字段。 加入字段“ JoinField”后,我只想保留行,其中“ DateVal”中的日值小于“日”的值。 但是,如果满足“ Day”的多个值的条件,我只希望它保留第一个实例。
在下面的第二个表中,对于JoinField“ A”有三行,对于第一行,我只希望它返回当月的日期在1-10之间的时间,第二行仅在当月的日期在11之间-20,最后20-31。
左联接或内部联接将带回所有值,我能想到的解决此问题的唯一方法是进行完整联接,只返回min(“ Day”)。 谁能想到一种更有效的方法?
提前致谢。
表格1
-------------------------------
| ID | JoinField | DateVal |
-------------------------------
| 1 | A | 01/01/2014 |
| 2 | A | 01/16/2014 |
| 3 | B | 05/20/2013 |
-------------------------------
表2
--------------------------------
| JoinField | Day | FieldToAdd |
--------------------------------
| A | 10 | A |
| A | 20 | AA |
| A | 31 | AAA |
| B | 15 | B |
| B | 31 | BB |
--------------------------------
所需结果
--------------------------------------------
| ID | JoinField | DateVal | FieldToAdd |
--------------------------------------------
| 1 | A | 01/01/2014 | A |
| 2 | A | 01/16/2014 | AA |
| 3 | B | 05/20/2014 | BB |
--------------------------------------------
您可以通过多种方式执行此操作。 我认为相关子查询是表达它的最简单方法,但是不幸的是,以下内容在Oracle中不起作用:
select t1.*,
(select *
from (select t2.*
from table2 t2
where t2.day < extract(day from t1.dateval)
order by t2.day desc
) t
where rownum = 1
)
from table1 t1;
您可以改为使用join
花式窗口函数执行此操作:
select *
from (select t1.*,
row_number() over (partition by t1.id order by t2.day desc) as seqnum
from table1 t1 left outer join
table2 t2
on t2.day < extract(day from t1.dateval)
) t
where seqnum = 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.