排除不需要的业务案例 - Oracle 12c

时间:2017-11-29 09:10:35

标签: sql oracle

我要求排除一些商业案例以过滤记录。

SQL FIddle链接:http://sqlfiddle.com/#!4/a130b/2

首先,我有一个车站表,其中包括车站号,车站所属的区域以及进站或出站的方向以及运行序号。

CREATE TABLE stns (stn number, dir varchar2(10), seq number , area varchar2(20));  


INSERT INTO stns VALUES (314,'In',1,'Houston');  
INSERT INTO stns VALUES (315,'In',2,'Houston');  
INSERT INTO stns VALUES (316,'In',3,'Houston');  
INSERT INTO stns VALUES (317,'In',4,'Houston');  
INSERT INTO stns VALUES (324,'Out',72,'Houston');  
INSERT INTO stns VALUES (311,'Out',73,'Houston');  
INSERT INTO stns VALUES (312,'Out',74,'Houston');  
INSERT INTO stns VALUES (313,'Out',75,'Houston');  
INSERT INTO stns VALUES (133,'In',82,'Blacktown');  
INSERT INTO stns VALUES (148,'In',83,'Blacktown');  
INSERT INTO stns VALUES (136,'In',84,'Blacktown');  
INSERT INTO stns VALUES (135,'In',85,'Blacktown');  
INSERT INTO stns VALUES (134,'In',86,'Blacktown');  
INSERT INTO stns VALUES (127,'Out',1,'Blacktown');  
INSERT INTO stns VALUES (126,'Out',2,'Blacktown');  
INSERT INTO stns VALUES (125,'Out',3,'Blacktown');  
INSERT INTO stns VALUES (124,'Out',4,'Blacktown');  
INSERT INTO stns VALUES (176,'Out',12,'Christtown');  
INSERT INTO stns VALUES (177,'Out',13,'Christtown');  
INSERT INTO stns VALUES (178,'Out',14,'Christtown');  
INSERT INTO stns VALUES (179,'Out',15,'Christtown');  
INSERT INTO stns VALUES (919,'In',38,'Albian');  
INSERT INTO stns VALUES (920,'In',39,'Albian');  
INSERT INTO stns VALUES (208,'In',41,'Albian');  
INSERT INTO stns VALUES (922,'In',42,'Albian');  

接下来,我有操作表,其中包含来源和目的地stn,小时数和顾客数量。

-1意味着我们不知道ostn或dstn在哪里.UNKNOWN

CREATE TABLE DEMO ( dt number, ostn number, ohr number, dstn number , dhr number, patrons number );  


INSERT INTO DEMO VALUES (20171101, -1,-1,919,1,4);   
INSERT INTO DEMO VALUES (20171101, -1,-1,920,2,3);   
INSERT INTO DEMO VALUES (20171101, 208,2,922,2,2);   
INSERT INTO DEMO VALUES (20171101, 314,3,316,2,2);   
INSERT INTO DEMO VALUES (20171101, 133,1,-1,-1,1);   
INSERT INTO DEMO VALUES (20171101, 133,2,134,2,4);   
INSERT INTO DEMO VALUES (20171101,1000,1,314,2,3);   
INSERT INTO DEMO VALUES (20171101,1000,1,315,2,3);   
INSERT INTO DEMO VALUES (20171101,1000,1,315,2,3);   
INSERT INTO DEMO VALUES (20171101,-1,-1,177,2,3);   
INSERT INTO DEMO VALUES (20171101,178,1,179,2,3);   
INSERT INTO DEMO VALUES (20171101,178,1,-1,-1,3);   
INSERT INTO DEMO VALUES (20171101,178,1,888,2,3);   
INSERT INTO DEMO VALUES (20171101,999,1,11,2,3);   
INSERT INTO DEMO VALUES (20171101,998,1,12,2,3);   
INSERT INTO DEMO VALUES (20171101,997,1,13,2,3);   
INSERT INTO DEMO VALUES (20171101,313,1,777,2,3);   
INSERT INTO DEMO VALUES (20171101,313,2,312,4,4);   
INSERT INTO DEMO VALUES (20171101,919,1,179,2,3);   
INSERT INTO DEMO VALUES (20171101,178,2,208,4,4);   
INSERT INTO DEMO VALUES (20171101, 12321,1, 124,1,3);  
INSERT INTO DEMO VALUES (20171101, 127,1, 124,1,3);  

接下来,我有一个配置表,其中包含业务案例,其中flag_ind告诉是否包含案例。 Y包括N是排除。

create table cnfg ( o_in number, o_out number, d_in number,d_out number,flag_ind char(1));  

INSERT INTO CNFG VALUES (1,0,1,0,'Y');  
INSERT INTO CNFG VALUES (0,0,1,0,'Y');  
INSERT INTO CNFG VALUES (0,0,0,1,'Y');  
INSERT INTO CNFG VALUES (1,0,0,1,'N');  
INSERT INTO CNFG VALUES (0,1,0,1,'Y');  
INSERT INTO CNFG VALUES (1,0,0,0,'Y');  
INSERT INTO CNFG VALUES (0,1,1,0,'N');  
INSERT INTO CNFG VALUES (0,1,0,0,'Y');  
INSERT INTO CNFG VALUES (0,0,0,0,'N');  

到此为止,我将转换演示表以找出o_in,o_out,d_in,d_out属性。我能够正确地获得逻辑(在这个社区的帮助下)

SELECT dt,  
       ostn,  
       ohr,  
       dstn,  
       dhr,  
       patrons,  
       CASE  
          WHEN ostn IN (SELECT stn  
                          FROM stns  
                         WHERE dir = 'In')  
          THEN  1 ELSE   0  
       END  o_in,  
       CASE  
          WHEN ostn IN (SELECT stn  
                          FROM stns  
                         WHERE dir = 'Out')  
          THEN 1 ELSE  0  
       END o_out,  
       CASE  
          WHEN dstn IN (SELECT stn  
                          FROM stns  
                         WHERE dir = 'In')  
          THEN 1  ELSE 0  
       END d_in,  
       CASE  
          WHEN dstn IN (SELECT stn  
                          FROM stns  
                         WHERE dir = 'Out')  
          THEN 1  ELSE  0  
       END  d_out  
  FROM demo; 

我可以使用cnfg加入表演示并排除那些情况     flag_ind是N.现在的问题是还有更多的业务案例     确定了从最终结果集中排除的那些需求

  1. 对于dir IN,客户在布莱克敦(Blacktown)轻拍,然后在走廊外开走
  2. 对于dir Out,客户在外面的走廊上轻敲了Blacktown
  3. 对于dir IN,客户在外面的走廊上轻拍,然后在休斯敦拍摄
  4. 对于dir OUT,客户在休斯顿轻拍并在走廊外开辟了对于休斯顿的情况我需要查看序号 并且只排除特定的stn细节,请查看 查询。
  5. select * FROM demo  
          WHERE ostn IN  
                   (SELECT stn  
                      FROM stns  
                     WHERE dir='In'  
                     AND area = 'Blacktown')  
                AND dstn NOT IN (SELECT stn FROM stns); -- Case1                                            
    
    
    select * FROM demo  
     WHERE dstn IN  
                  (SELECT stn  
                      FROM stns  
                     WHERE dir='Out'  
                     AND area = 'Blacktown')  
                AND ostn NOT IN (SELECT stn FROM stns);   -- Case2  
    
    
    
     select * FROM demo             
       WHERE (dstn IN  
                    (SELECT stn  
                       FROM stns  
                      WHERE     dir = 'In'  
                            AND area = 'Houston'  
                            AND seq = 1)  
                 AND ostn NOT IN (SELECT stn FROM stns));  -- Case3              
    
    
    select * from demo  
      WHERE (ostn IN  
                    (SELECT stn  
                       FROM stns  
                      WHERE     dir = 'Out'  
                            AND area = 'Houston'  
                            AND seq = 75)  
                 AND dstn NOT IN (SELECT stn FROM stns)); -- Case4 
    

    您是否可以指导或帮助排除上述案例以及cnfg表中提到的案例。?

1 个答案:

答案 0 :(得分:0)

with t1 as (
    select dm.dt, dm.ostn, dm.ohr, dm.dstn, dm.dhr, dm.patrons,
           so.area area_in,  so.dir dir_in,  so.seq seq_in, 
           sd.area area_out, sd.dir dir_out, sd.seq seq_out, 
           case when so.dir  = 'In'  then 1 else 0 end o_in,
           case when so.dir  = 'Out' then 1 else 0 end o_out,
           case when sd.dir  = 'In'  then 1 else 0 end d_in,
           case when sd.dir  = 'Out' then 1 else 0 end d_out
      from demo dm 
        left join stns so on dm.ostn = so.stn
        left join stns sd on dm.dstn = sd.stn),
t2 as (
    select * 
      from t1
      join cnfg using (o_in, o_out, d_in, d_out)
      where flag_ind = 'Y')
select * 
  from t2
  where not (   
       (area_in = 'Blacktown' and dir_in = 'In' and area_out is null)
    or (area_in is null and area_out = 'Blacktown' and dir_out = 'Out') 
    or (area_in is null and area_out = 'Houston'   and dir_out = 'In') 
    or (area_in = 'Houston' and dir_in = 'Out' and seq_in = 75 and area_out is null) )

<强> SQL Fiddle

  • 第一步(子查询t1) - 连接表stations两次,这为您提供清晰,可读的图片。同时在此处指定o_in, o_out, d_in, d_out
  • 第二步(t2) - 使用这些值连接配置表并排除不需要的标志,
  • 最后一步 - 从上面的结果中排除了四个不需要的案例。

修改

  

如果我需要用max(seq)和替换seq_in = 75和seq_out = 1   min(seq)of houstons,那我该怎么办呢。

seq_in = 75替换为seq_in = (select max(seq) from stns where area = 'Houston')

  

我想排除那些关闭seq数量较少的记录   而不是点击序号。例如,检查运输是否倒退   从seq 4到seq 3或2

... or (seq_in is not null and seq_out is not null and seq_in > seq_out)