我有一个名为PRODUCTS
的表,每个PRODUCT_NO_REGISTRATION_NO
只允许使用一次产品开始日期,并且返回日期不应该发生冲突。
我们退回产品并在ACTUAL_RETURN_DATE
中输入退货日期,如果ACTUAL_RETURN_DATE
为空,我们将END_DATE
作为退货日期。
您可以看到记录here
例如PRODUCT_NO_REGISTRATION_NO is clashing, as HP_2014 is returned on 18-Jun-2001, however HP_2012 same PRODUCT_NO_REGISTRATION_NO is allotted on 18-Jun-2001.
如何使用sql找出记录是否重叠?
更新1
表PRODUCTS
中有一项修改要包括PRODUCT_EXTENSION_NO
。
PRODUCT_NO,PRODUCT_NO_REGISTRATION_NO and PRODUCT_EXTENSION_NO
的组合成为唯一的行(复合主键)。
规则如下
每个PRODUCT_NO_REGISTRATION_NO
仅允许在产品开始日期使用一次,并且返回日期不应发生冲突。
我们退回产品并在ACTUAL_RETURN_DATE
中输入退货日期,如果ACTUAL_RETURN_DATE
为空,我们将END_DATE
作为退货日期。
PRODUCT_NO
有扩展名,因此END_DATE
已延长。
E.g。如果你看到记录
PRODUCT_NO
- ORP76
与PRODUCT_EXTENSION_NO
- 1
与PRODUCT_NO
- ORP100
与PRODUCT_EXTENSION_NO
- 0
发生冲突。
如何使用sql找出记录是否重叠,但允许PRODUCT_NO
的扩展名。即扩展名为PRODUCT_NO
的{{1}} ORP76
和扩展名1基本上已扩展。
答案 0 :(得分:1)
假设product_no
是唯一的,您可以自行加入产品表并检查overlapping dates:
select *
from PRODUCTS
inner join products products_test
on products.PRODUCT_NO_REGISTRATION_NO
= products_test.PRODUCT_NO_REGISTRATION_NO
and products.start_date
<= nvl (products_test.ACTUAL_RETURN_DATE, products_test.end_date)
and nvl (products.ACTUAL_RETURN_DATE, products.end_date)
>= products_test.start_date
and products.product_no
<> products_test.product_no
编辑:使用rowid的版本:
select *
from PRODUCTS
inner join products products_test
on products.PRODUCT_NO_REGISTRATION_NO
= products_test.PRODUCT_NO_REGISTRATION_NO
and products.start_date
<= nvl (products_test.ACTUAL_RETURN_DATE, products_test.end_date)
and nvl (products.ACTUAL_RETURN_DATE, products.end_date)
>= products_test.start_date
and products.rowid
<> products_test.rowid
澄清之后 更新:我们的想法是在extended
条记录中获取产品开始日期和结束日期的最小和最大范围,然后比较两个流,以便范围重叠去除自引用通过测试product_no和product_no_registration_no。
with extended as
(
select PRODUCT_NO,
PRODUCT_NO_REGISTRATION_NO,
min (START_DATE) as start_date,
max (nvl (ACTUAL_RETURN_DATE, END_DATE)) as end_date
from products
group by PRODUCT_NO, PRODUCT_NO_REGISTRATION_NO
)
select e1.PRODUCT_NO_REGISTRATION_NO,
e1.PRODUCT_NO,
e1.start_date,
e1.end_date,
e2.PRODUCT_NO "PRODUCT_NO - CLASH",
e2.start_date "START_DATE - CLASH",
e2.end_date "END_DATE - CLASH"
from extended e1
inner join extended e2
on e1.PRODUCT_NO_REGISTRATION_NO
= e2.PRODUCT_NO_REGISTRATION_NO
and e1.start_date <= e2.end_date
and e1.end_date >= e2.start_date
-- Remove self-references
and not
(
e1.PRODUCT_NO = e2.PRODUCT_NO
and e1.PRODUCT_NO_REGISTRATION_NO
= e2.PRODUCT_NO_REGISTRATION_NO
)