【问题标题】:Excluding the unwanted business cases - Oracle 12c排除不需要的业务案例 - Oracle 12c
【发布时间】:2018-05-12 22:25:00
【问题描述】:

我需要排除一些业务案例来过滤记录。

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

接下来,我有操作表,其中包含起点和终点站、营业时间和顾客数量。

-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 详细信息,请查看 查询。
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表中提到的情况。

【问题讨论】:

    标签: sql oracle


    【解决方案1】:
    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) - 使用这些值加入配置表并排除不需要的标志,
    • 最后一步 - 从上述结果中排除四个不需要的情况。

    编辑:

    如果我需要将 seq_in = 75 和 seq_out = 1 替换为 max(seq) 和 min(seq) of houstons,那我应该如何处理这个案子。

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

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

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

    【讨论】:

    • 谢谢,我用实物测试一下,告诉你。
    • 谢谢,我会用实物测试这个,让你知道。我有两个问题,如果我需要用休斯顿的 max(seq) 和 min(seq) 替换 seq_in = 75 和 seq_out = 1,那么我应该如何处理这个案例。另一个问题是如果我想排除那些 tap off seq number 小于 tap on seq number 的记录。例如检查传输是否从 seq 4 倒退到 seq 3 或 2 .. 如何检查这些情况并排除。例如 ostn = 313 和 dstn = 312 ...
    • 感谢@ponder Stibbons,它在我的情况下运行良好。唯一需要注意的是处理 NOT 子句未处理的空值。你认为这种情况是否可以放入另一个表中,并且可以像 cnfg 表一样加入回来过滤掉。
    • 在处理空值时我们必须非常小心。例如,您不能将它们包含在 IN 子句中。你必须检查IS NULLIS NOT NULL,简单的比较是行不通的。请在本主题中查找一些问题和答案,例如thisthis
    • 我只是使用了 NVL(area_in,'-1') 然后在 where 子句中使用了 area_in ='-1'.... 像这样转换了所有内容
    猜你喜欢
    • 2014-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    相关资源
    最近更新 更多