SQL:类似交集的问题……使用历史数据进行树导航时出现问题

时间:2019-03-20 11:05:03

标签: sql hierarchical-data

有什么方法可以补充SQL中两条记录之间的交集吗?

例如,我有两条记录:

@Pipe({ name: 'temperature' })
export class TemperaturePipe implements PipeTransform {
  transform(value: number): string {
    if (value > 0 && value <= 10) {
      return 'dark-blue';
    }else if (value > 11 && value <= 20) {
      return 'mid-blue';
    }else if (value > 21 && value <= 30) {
      return 'light-blue';
    }else if (value > 31 && value <= 39) {
      return 'aqua';
    }else if (value > 40 && value <= 45) {
      return 'yellow';
    }else if (value > 46 && value <= 49) {
      return 'light-orange';
    }else if (value > 50 && value <= 70) {
      return 'red';
    } else {
      return '';
    }
  }
}

我想得到

KEY BEG_DATE END_DATE FATHER DEEP
K1  1 jan    30 jun   F1      0
K1  1 jan    31 dec   F2      1

实际情况是,我有一些组织单位,这些组织单位必须引用组织单位的父亲,并且可以引用成本中心。如果与成本中心没有明确的关系,则当前的组织单位将从父亲(或其祖先...)那里继承成本中心。

通过非常复杂的语句,我得到了结果,但是如果我与Cost Center有显式关系(在引用组织单位结束之前已关闭),则我的SQL无法正常工作,而我无法执行(或更多)以上步骤

只需尝试SqlFiddle

DDL

KEY BEG_DATE END_DATE FATHER DEEP
K1  1 jan    30 jun   F1      0
K1  1 jul    31 dec   F2      1

DML

CREATE TABLE Org (
  IDOrg char(6),
  Beg_O DATE,
  End_O DATE);

CREATE TABLE Org_REL (
  IDOrg char(6),
  IDOrgFather char(6),
  Beg_OO date,
  End_OO date);

CREATE TABLE Org_Cost (
  IDOrg char(6),
  IDCostCenter char(10),
  Beg_OC date,
  End_OC date);

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

INSERT INTO Org
  SELECT 'Org0', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org1', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org2', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org3', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx1', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx2', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx3', '2018-01-01', '9999-12-31' FROM DUAL ;

INSERT INTO Org_REL 
  SELECT 'Org1', 'Org0', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org2', 'Org0', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org3', 'Org1','2018-01-01', '2018-06-30' FROM DUAL UNION
  SELECT 'Org3', 'Org2','2018-07-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx1', 'Org3','2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx2', 'Org3','2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx3', 'Org1','2018-01-01', '9999-12-31' FROM DUAL;

INSERT INTO Org_Cost 
  SELECT 'Org0', 'Cost0', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org1', 'Cost1', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Org2', 'Cost2', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx1', 'Cost_x1', '2018-01-01', '9999-12-31' FROM DUAL UNION
  SELECT 'Orgx3', 'Cost_x3', '2018-01-01', '2018-07-31' FROM DUAL ;

我得到以下记录

select
    CONNECT_BY_ROOT Org.IDOrg LEAF,
    Org_REL.IDOrg,
    Org_REL.IDOrgFather,
    Org_REL.Beg_OO Beg_OO,
    Org_REL.End_OO End_OO,
    level DEEP,
    SYS_CONNECT_BY_PATH(Org_REL.IDOrg, '*') path
from 
    Org
    LEFT OUTER JOIN Org_REL on Org.IDOrg = ORG_Rel.IDOrg
WHERE 1=1
CONNECT BY --NOCYCLE 
  PRIOR Org_REL.IDOrgFather = Org_REL.IDOrg
UNION
SELECT
    IDOrg, null, IDOrg, BEG_O, END_O, 0, '*' || IDOrg
FROM Org
)
, 

final as (
select 
  LEAF, PATH, DEEP, IdOrgFather, IDCostCenter, 
  TO_CHAR(CASE 
    WHEN t.Beg_OO < oc.Beg_OC THEN oc.Beg_OC 
    ELSE t.Beg_OO
  END, 'YYYY-MM') BEGVAL, 
  TO_CHAR(CASE 
    WHEN t.End_OO > oc.End_OC THEN oc.End_OC 
    ELSE t.End_OO
  END, 'YYYY-MM') ENDVAL
  , RANK() OVER (PARTITION BY LEAF ORDER BY DEEP) ORD
from 
  tree t left outer join
  Org_Cost oc on t.IDOrgFather = oc.IDOrg
WHERE
    IDCostCenter is not null
)
--SELECT * FROM FINAL WHERE leaf = 'Orgx3'

select
LEAF, IDCostCenter, BEGVAL, ENDVAL, ORD
from final 
WHERE 
  LEAF IN ('Orgx1', 'Orgx2', 'Orgx3') 
  AND ORD = 1

夹心

  • 第一个是OK(明确的关系)
  • 第二个和第三个都可以(没有显式关系,可以继承层次结构)
  • 第四部分是正确的,因为我也希望在'2018-07'之后的继承关系

如果我删除了获得的| LEAF | IDCOSTCENTER | BEGVAL | ENDVAL | ORD | |--------|--------------|---------|---------|-----| | Orgx1 | Cost_x1 | 2018-01 | 9999-12 | 1 | | Orgx2 | Cost1 | 2018-01 | 2018-06 | 1 | | Orgx2 | Cost2 | 2018-07 | 9999-12 | 1 | | Orgx3 | Cost_x3 | 2018-01 | 2018-07 | 1 | 条款(仅适用于orgx3)

AND ORD = 1

已经捕获了解雇记录,但是第二个记录应该不是在2018-01年开始,而是从2018-08年开始

0 个答案:

没有答案