如何判断子表中的完全相同

时间:2017-07-25 03:44:04

标签: sql oracle

在我的Oracle数据库中,我有2个表dw

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'
;

0 个答案:

没有答案