在我的Oracle数据库中,我有2个表d
和w
:
table d
INVOICECODE VARCHAR2(32 BYTE) PRIMARY KEY
COMBINATIONNAME NVARCHAR2(100 CHAR)
STARTTIME DATE
ENDTIME DATE
STATUS NUMBER(10,0)
.....
table w
SERIALID VARCHAR2(32 BYTE) PRIMARY KEY
INVOICECODE VARCHAR2(32 BYTE)
WARECODE VARCHAR2(20 BYTE)
WARENAME NVARCHAR2(100 CHAR)
....
当我在WEB UI上添加或编辑数据时,我必须验证STATUS
时间不重叠且子表数据不能完全相同。
e.g。新数据
StartTime: 2017/07/25
EndTime: 2017/07/28
WareCode WareName
123 A
222 B
如果w
表中有两行日期(WareCode:123,222),满足条件,则无法添加新数据;
如果WareCode:123或WareCode:123,222,456,可以添加新数据。如何编写sql:
select count(1) from d
where status = 1
and (StartTime BETWEEN '2017-07-25' AND '2017-07-28'
OR EndTime BETWEEN '2017-07-25' AND '2017-07-28'
OR '2017-07-25' Between StartTime AND EndTime
OR '2017-07-28' BETWEEN StartTime AND EndTime)
and (/*....*/)
样本数据
表d:
|----------------------------------------------------------------------------------|
| INVOICECODE | COMBINATIONNAME | STARTTIME | ENDTIME | STATUS |
|----------------------------------------------------------------------------------|
| 1101 | GoodsCombination1 | 2017-07-10 00:01 | 2017-07-20 15:00 | 0 |
|----------------------------------------------------------------------------------|
| 1105 | GoodsCombination2 | 2017-07-24 15:00 | 2017-07-26 15:00 | 1 |
-----------------------------------------------------------------------------------|
| 210 | GoodsCombination3 | 2017-07-26 12:00 | 2017-07-27 15:00 | 1 |
-----------------------------------------------------------------------------------|
| 88 | GoodsCombination4 | 017-07-25 09:00 | 2017-07-26 09:00 | 1 |
------------------------------------------------------------------------------------
STATUS列可以是0,1,2(未审核,已审核,已拒绝)
表w使用INVOICECODE关联表d
表格w:
|----------------------------------------------|
| SERIALID | INVOICECODE | WARECODE | WARENAME |
|----------------------------------------------|
| 1 | 1101 | 123 | A |
|----------------------------------------------|
| 2 | 1105 | 123 | A |
-----------------------------------------------|
| 3 | 1105 | 222 | B |
-----------------------------------------------|
| 4 | 1105 | 300 | D |
-----------------------------------------------|
| 5 | 210 | 123 | A |
-----------------------------------------------|
| 6 | 210 | 222 | B |
-----------------------------------------------|
| 7 | 88 | 123 | A |
-----------------------------------------------|
| 8 | 88 | 300 | D |
------------------------------------------------
当像这样的新数据时,可以插入db:
CombinationName: aaaaa
StartTime: 2017-07-20 00:00:00
EndTime: 2017-07-23 00:00:00
WareCode WareName
222 B
300 D
像这样,不能插入db,因为210'status = 1并且表d中有两个相同的数据:
CombinationName: aaaaa
StartTime: 2017-07-20 00:00:00
EndTime: 2017-07-23 00:00:00
WareCode WareName
123 A
222 B
无法插入db,因为状态= 1且表d中的时间重叠为1105,210,88:
CombinationName: aaaaa
StartTime: 2017-07-25 00:00:00
EndTime: 2017-07-27 00:00:00
WareCode WareName
123 A
222 B
44 F
可能为WareCode排序新数据,然后使用下面的SQL:
Select Count(1) From (
Select (
Select
listagg(WareCode, ';') within group (Order by WareCode) as mergeWareCode
From w
Where InvoiceCode = d.InvoiceCode
Group by InvoiceCode
) as mergeWareCode, d.InvoiceCode From d
Where d.Status = 1 and ( StartTime Between to_date('2017-07-25','yyyy-mm-dd hh24:mi:ss') and to_date('2017-07-28','yyyy-mm-dd hh24:mi:ss')
or EndTime Between to_date('2017-07-25','yyyy-mm-dd hh24:mi:ss') and to_date('2017-07-28','yyyy-mm-dd hh24:mi:ss')
or to_date('2017-07-25','yyyy-mm-dd hh24:mi:ss') Between StartTime and EndTime
or to_date('2017-07-28','yyyy-mm-dd hh24:mi:ss') Between StartTime and EndTime )
) Where mergeWareCode='123;222'
;