【问题标题】:For each row of one table, count entries in another table pointing to each of those rows in Oracle对于一个表的每一行,计算另一个表中指向 Oracle 中每一行的条目
【发布时间】:2012-10-21 20:46:49
【问题描述】:

不确定标题是否能很好地说明问题;这就是我正在使用的,

我有以下表格,

-- table = kms_doc_ref_currnt_v
DOC_ID    VARCHAR2(19)
TO_DOC_ID    VARCHAR2(19)
BRANCH_ID    NUMBER(8)
REF_TYP_CD    VARCHAR2(20)

-- table = kms_fil_nm_t
DOC_ID    VARCHAR2(19)    PRIMARY KEY    UNIQUE

例如,通过此查询,我可以计算所有具有to_doc_id = 59678kms_doc_ref_currnt_v 记录,其中59678 是kms_fil_nm_t 中的一个值,

select 'doc_id 59678 has ' || count(to_doc_id) as cnt from kms_doc_ref_currnt_v where branch_id=1 and ref_typ_cd in ('CONREF', 'KBA') and to_doc_id=59678;

kms_doc_ref_currnt_v.to_doc_id 是具有kms_fil_nm_t.doc_id 值之一的字段。 kms_doc_ref_currnt_v.doc_id 也是kms_fil_nm_t 中的值之一。

我正在寻找的单个查询将遍历每个 kms_fil_nm_t.doc_id 并计算 kms_doc_ref_currnt_v 中具有相似 to_doc_id 的所有行。返回的每一行看起来都像上面查询的输出。这是示例输出,

doc_id 1 has 32
doc_id 2 has 314
doc_id 3 has 2718
doc_id 4 has 42
doc_id 5 has 128
doc_id 6 has 11235
.
.
.

可能很简单,但我就是想不通。

【问题讨论】:

    标签: oracle join group-by


    【解决方案1】:

    对两个表进行连接并添加GROUP BY 子句,如下所示:

        SELECT 'doc_id 59678 has ' || count(to_doc_id) as cnt 
        FROM kms_doc_ref_currnt_v kv, kms_fil_nm_t kt
        WHERE kt.doc_id= kv.to_doc_id 
              AND kv.branch_id=1 
              AND kv.ref_typ_cd in ('CONREF', 'KBA') 
              AND kv.to_doc_id=59678
        GROUP BY kv.to_doc_id;     
    

    编辑:

    要从kms_doc_ref_currnt_v 获取所有记录,无论它们在kms_fil_nm_tkv.to_doc_id=59678 中的参考可用性如何,请执行以下操作:

        SELECT 'doc_id 59678 has ' || count(to_doc_id) as cnt 
        FROM kms_doc_ref_currnt_v kv 
             LEFT JOIN kms_fil_nm_t kt
             ON (kt.doc_id= kv.to_doc_id )
        WHERE  kv.branch_id=1 
              AND kv.ref_typ_cd in ('CONREF', 'KBA') 
        GROUP BY kv.to_doc_id; 
    

    要替换硬编码59678,您可能需要编写:

        SELECT 'doc_id ' || kt.doc_id || ` has ' || count(to_doc_id) as cnt 
        FROM kms_doc_ref_currnt_v kv 
             LEFT JOIN kms_fil_nm_t kt
             ON (kt.doc_id= kv.to_doc_id )
        WHERE  kv.branch_id=1 
              AND kv.ref_typ_cd in ('CONREF', 'KBA') 
        GROUP BY kv.to_doc_id, kt.doc_id; 
    

    【讨论】:

    • 这很接近但不是我想要的。 AND kv.to_doc_id=59678 部分应省略。我想知道kms_fil_nm_t 中的每个doc_id 有多少引用。现在大约有 18k doc_ids。对于其中的每一个,我需要知道kms_doc_ref_currnt_v 中有多少记录具有与doc_id 匹配的to_doc_id。几乎可以工作, SELECT ' has ' || count(kv.to_doc_id) as cnt FROM kms_doc_ref_currnt_v kv, kms_fil_nm_t kt WHERE kt.doc_id = kv.to_doc_id AND kv.branch_id=1 AND kv.ref_typ_cd in ('CONREF', 'KBA') GROUP BY kv.to_doc_id ORDER BY cnt降序;返回 6k 行。
    • @wsams:我在这里遗漏了一些东西。一旦您省略了AND kv.to_doc_id=59678,仍然无法正常工作。如果没有任何参考,它是否像 kms_doc_ref_currnt_v 中缺少的记录?如果是,请在答案中参考我更新的查询。
    • 是的,我期待看到所有记录,即使它们的计数为 0,但假设我真的不需要这些信息。
    • 实际上,我只是有点过激了。在您的编辑中,该查询有效,但我真的需要知道哪个doc_ids 与计数相符。但是当我有多个连接时,我会收到 not a GROUP BY expression 错误。所以我需要select kt.doc_id || ' has ' || count(to_doc_id) 之类的东西,而不是select 'doc_id 59678 has ' || count(to_doc_id)
    • @wsams You need to put all attributes being used in select in group by clause。请参考更新后的答案。
    【解决方案2】:

    您需要在具有所有doc_id 值的驱动表和可能有也可能没有匹配条目的依赖表之间使用outer join;和 group by 子句来定义聚合函数 (count()) 的操作对象。比如:

    select 'doc_id ' || t.doc_id || ' has ' || count(*)
    from kms_fil_nm_t t
    left join kms_doc_ref_currnt_v v
    on v.to_doc_id = t.doc_id
    and v.branch_id = 1
    and v.ref_typ_cd in ('CONREF', 'KBA')
    group by t.doc_id;
    

    这假设您想知道何时不使用 doc_id,因此您需要像 doc_id 1234 has 0 这样的条目。如果您不想看到那些,那么您可以使用内部连接而不是外部连接 - 基本上只需删除单词 left - 但如果是这种情况,那么您根本不需要加入,您可以做吧:

    select 'doc_id ' || v.to_doc_id || ' has ' || count(*)
    from kms_doc_ref_currnt_v v
    where v.branch_id = 1
    and v.ref_typ_cd in ('CONREF', 'KBA')
    group by v.to_doc_id;
    

    除非有to_doc_id 值在另一个表中,否则将包含在此查询的结果中,但如果表已连接,则排除。

    【讨论】:

    • 如果我删除连接的前两个部分,这可以正常工作。即'doc_id ' || t.doc_id || 否则我会收到not a GROUP BY expression 错误。
    • @wsams - 是的,这就是我不测试代码时发生的情况;我按错误的字段分组。
    猜你喜欢
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 2019-09-11
    • 2021-11-06
    • 1970-01-01
    • 2022-01-04
    • 2011-08-15
    相关资源
    最近更新 更多