【问题标题】:create Oracle View to compare data based on conditions创建 Oracle 视图以根据条件比较数据
【发布时间】:2021-01-10 14:49:55
【问题描述】:

我有以下表格:

    CREATE TABLE
        IS_ID
        (        
            FUND_ISIN VARCHAR2(12) NOT NULL,
            FUND_QUOTE_CRNY VARCHAR2(5),       
            MEMBER_DESCR VARCHAR2(5),
            MEMBER_RATIO NUMBER(19,8),
            ALLOCATIONASSETTYPE VARCHAR2(100)
        );
    
    CREATE TABLE
        IS_ID_TST
        (        
            FUND_ISIN VARCHAR2(12) NOT NULL,
            FUND_QUOTE_CRNY VARCHAR2(5),       
            MEMBER_DESCR VARCHAR2(5),
            MEMBER_RATIO NUMBER(19,8),
            ALLOCATIONASSETTYPE VARCHAR2(100)
        );

    

我想创建这样的视图:

  1. 对于两个表中常见的fund_isin 字段值,检查member_descr = 'O'member_ratio 字段并从member_ratio 字段值较低的表中取出fund_isin 的所有行。对于member_descr = 'O',如果IS_ID_TST 表中的member_ratio 对于任何fund_isin 小于0,则始终从IS_ID_TST 表中获取所有数据(在这种情况下,我们不需要比较IS_ID 表中的数据会员比例低)

  2. 如果fund_isin 存在于一个表中但不存在于另一个表中,则取所有这些行(双向)。

  3. 对于所有其他 fund_isin,仅从表 IS_ID_TST 表中获取所有这些行(这可能涵盖第 1 点和第 2 点)

【问题讨论】:

  • 对于点For member_descr = 'O', if the member_ratio in IS_ID_TST table is less than 0 for any fund_isin then always take all the data from IS_ID_TST table(in this case we dont need to compare data from IS_ID table for low member ratio ....这种情况是否仅适用于两个表中的公共记录,或者无论它是否在两个表中都可用,或者不总是采用 IS_ID_TST 表中的比率列?
  • 我们总是从 IS_ID_TST 表中获取 member_ratio 中
  • 这意味着对于普通记录,我们只需要考虑配给值 > 0。我说的对吗?
  • 对于 member_descr = 'O' 是,当来自 IS_ID_TST 表的 member_ratio 值 > 0 时,然后检查 IS_ID 和 IS_ID_TST 表中的常见记录,并从各个表中取出所有具有低比率的行......以前对于低比率我们从表中只取 member_descr = 'O' 的行,但现在我们必须为各自的 fund_isin 取所有行...
  • 好的。想起来很复杂,但我可以验证您在问题中提到的要点并查看

标签: oracle select view


【解决方案1】:

您能否检查以下查询,我已在 with 子句中创建所有案例,然后将其合并。

编辑:- 在与 OP 通过聊天讨论和澄清后

我们不再需要full join,并且通过访问每个案例的表来重写它。

-- case 1
-- when fund_isin with member_ratio = 'O' present in both is_id and is_id_tst table
-- and the value of is_id.member_ratio < is_id_tst.memebr_ratio
-- logic --
-- the from clasuse says take all the records from is_id table 
-- by corelate the fund_isin (t1.fund_isin = t.fund_isin)
-- the subquery then finds record by joining both table is_id and is_id_tst for member_ratio = 'O'
-- and where the member_ratio is smaller (is_id_tst.member_ratio > is_id.member_ratio)
-- extra condition on is_id_tst table is the member_ratio value should be greater than 0 for member_descr='O'
WITH ratio_lower_is_id
AS
(SELECT *
   FROM is_id t
  WHERE EXISTS 
  (SELECT 1
     FROM is_id_tst t2
     JOIN is_id t1
       ON t2.fund_isin = t1.fund_isin
    WHERE t1.fund_isin = t.fund_isin
      AND t2.member_descr = 'O'
      AND t1.member_descr = 'O'
      AND t2.member_ratio > 0
      AND t2.member_ratio > 
          t1.member_ratio)
),
-- case 2
-- applies the same logic as in case 1 but then take records from is_id_tst table
-- where the member_ratio having lower value for record with member_descr='O'
-- in comparison with the record present in is_id table for memebr_descr='O'
ratio_lower_is_id_tst
AS
(SELECT *
   FROM is_id_tst t
  WHERE t.member_ratio > 0
    AND EXISTS 
  (SELECT 1
     FROM is_id t2
     JOIN is_id_tst t1
       ON t2.fund_isin = t1.fund_isin
    WHERE t1.fund_isin = t.fund_isin
      AND t2.member_descr = 'O'
      AND t1.member_descr = 'O'
      AND t2.member_ratio > 
          t1.member_ratio)
),
-- case 3
-- take all records from is_id_tst table for all each unique fund_isin 
-- where the member_ratio value is < 0 for record member_descr='O'
-- and is avaialble in is_id_tst table irrespective of what record for the same
-- fund_isin available in is_id table
ratio_minus_is_id_tst
AS
(SELECT *
   FROM is_id_tst t
  WHERE EXISTS 
  (SELECT 1
     FROM is_id_tst t1
    WHERE t1.fund_isin = t.fund_isin
      AND t1.member_descr = 'O'
      AND t1.member_ratio < 0)
),
-- case 4
-- take all the records from is_id table 
-- where the fund_isin is not available in is_id_tst table
only_in_is_id
AS
(
SELECT *
  FROM is_id t1
 WHERE NOT EXISTS
   (SELECT 1 
      FROM is_id_tst t2
     WHERE t2.fund_isin = t1.fund_isin)
),
-- case 5
-- take all the records from is_id_tst table
-- where the fund_isin is not available in is_id table
only_in_is_id_tst
AS
(
SELECT *
  FROM is_id_tst t1
 WHERE NOT EXISTS
   (SELECT 1 
      FROM is_id t2
     WHERE t2.fund_isin = t1.fund_isin)
)
-- finally once all the sets as per each case available
-- take each of them and do a union all for the final result set
-- one level sub query required only if we want to sort the result otherwise can be removed
-- and only union all of all sets from with clause is enough
select *
  from 
(
-- case1
select *
  from ratio_lower_is_id
union all
-- case 2
select *
  from ratio_lower_is_id_tst
union all
-- case 3
select *
  from ratio_minus_is_id_tst
union all
-- case 4
select *
  from only_in_is_id
union all
-- case 5
select *
  from only_in_is_id_tst
)
order by fund_isin;

【讨论】:

  • 对于 fund_isin H000526,我们必须从 IS_IS 表中取出所有行,因为它在 IS_ID_TST 表中不存在......它的第 2 点有问题
  • 这里有一个问题..你为什么要为 t1.fund_quote_crny = t2.fund_quote_crny 和 t1.member_descr = t2.member_descr ..在某个地方进行连接,因为我认为 fund_isin 是表之间比较的关键并且 member_descr 值也可以不同,两个表中的其他字段对于相同的 fund_isin ?
  • 对于 H000526 ,有一条记录为 'O' 和 onw 为 'C' 但结果显示 2 条记录为 'C' ,如何?我只在需要配对记录检查的地方加入。我不确定如果没有这个加入,你会怎么想,那将是完全不同的逻辑。例如,D000123IS_ID 表中有三个记录,MEMBER_DESCR 为 null,哪个逻辑涵盖了这个?
  • 对不起,我错了,这是拼写错误。我更正了 H000526 和 D000123 的相关记录...实际上配对记录意味着什么?因为对于 member_descr = 'O' 通常我们只是根据常见的 fund_isin 比较记录还是fund_isin根本不存在?
  • 检查dbfiddle.uk/… .... 我在ratio_minus_is_id_tst 的情况下添加了一个额外的或条件,以使用O 记录is_id 表中不存在的记录。
猜你喜欢
  • 2021-01-08
  • 2019-04-10
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 2020-11-25
  • 2018-06-22
  • 1970-01-01
相关资源
最近更新 更多