如何根据子表值映射相同表的行?

时间:2017-04-25 00:42:43

标签: sql oracle select join stored-procedures

我需要编写生成表或视图的SQL,其中包含一个实体到另一个实体的映射,其中实体属于同一个表,映射条件基于其子项的值。假设我有以下架构:

Schema Illustration

我需要能够根据以下条件在两个不同的实体ID(称为A和B)之间创建映射:

  1. 链接到实体A的Person链接的Category的Category.Name值必须与链接到实体B的Person链接的Category的Name.Name值相同(“每个实体的验证名称必须匹配“)

  2. 与实体A关联的验证必须与链接到实体B的验证具有相同的VerificationValue(“两个实体的验证值必须匹配”)

  3. 链接到与实体A链接的验证的VerificationType.Name必须与链接到与实体B链接的验证的VerificationType.Name相同(“每个实体的验证类型必须匹配“)

  4. 最终结果将像TABLE或VIEW一样:

    entity_ID_A | entity_ID_B
    --------------------------
    1             2
    3             4
    11            10
    

    为简单起见,假设我们不能将多个值映射到entity_ID_A

    在代码中,这可以简单地表达为:

    Entity a, b = //do some stuff to get the two different entities
    return a.person.name == b.person.name &&
        a.verification.verificationValue == b.verificationValue &&
        a.verification.verificationType.name == b.verification.verificationType.Name;
    

    我甚至不确定从哪里开始在SQL中表达这一点,更不用说生成符合此条件的实体ID映射表。在进行任何比较之前,我是否一起加入所有表格?任何正确方向的指针都将受到赞赏

1 个答案:

答案 0 :(得分:1)

是。首先加入所有表格,然后进行自我加入:

with ents as (
    select e.id, c.name cname, v.verificationvalue vval, vt.name vname
      from entity e
      join person p on e.person_id = p.id
      join category c on c.id = p.category_id
      join verification v on v.id = e.verification_id
      join verificationtype vt on vt.id = v.verificationtype_id)
select a.id id_a, b.id id_b
    from ents a
    join ents b on a.id < b.id
               and a.cname = b.cname
               and a.vval = b.vval
               and a.vname = b.vname