如何在 Oracle 中使用分区获取记录计数

Posted

技术标签:

【中文标题】如何在 Oracle 中使用分区获取记录计数【英文标题】:How to Get a Count of Records Using Partitioning in Oracle 【发布时间】:2018-11-12 01:36:32 【问题描述】:

我有以下疑问:

SELECT 
    F.IID, 
    F.E_NUM AS M_E_NUM, 
    MCI.E_NUM AS MCI_E_NUM, 
    F.C_NUM AS M_C_NUM, 
    MCI.C_NUM AS MCI_C_NUM,
    F.ET_ID AS M_ET_ID, 
    EDIE.ET_ID AS ED_INDV_ET_ID,
    COUNT(*) OVER (PARTITION BY F.IID) IID_COUNT
FROM FT_T F JOIN CEMEI_T MCI ON F.IID = MCI.IID
    JOIN EDE_T EDE ON MCI.E_NUM = EDE.E_NUM
    JOIN EDIE_T EDIE ON EDIE.IID = F.IID AND EDIE.ET_ID = EDE.ET_ID
WHERE 
    F.DEL_F = 'N'
    AND MCI.EFF_END_DT IS NULL
    AND MCI.TOS = 'BVVB'
    AND EDE.PTEND_DT IS NULL
    AND EDE.DEL_S = 'N'
    AND EDE.CUR_IND = 'A'
    AND EDIE.TAR_N = 'Y'
    AND F.IID IN
        (
         SELECT DISTINCT IID 
         FROM FT_T 
         WHERE GROUP_ID = 'BG' 
            AND DEL_F = 'N' 
            AND (IID, E_NUM) NOT IN 
                (
                 SELECT IID, E_NUM FROM CEMEI_T 
                 WHERE TOS = 'BVVB' AND EFF_END_DT IS NULL
                )
        );

我基本上是从几个表中获取信息并为它们创建一个平面记录。

除了现在我需要查明FT_T 表中是否有两条具有相同IID 的记录并将其显示为结果集的一部分之外,一切都相应地工作。

我尝试使用分区,但结果集中的所有行都返回一个计数,即使 FT_T 中有 2 条具有相同 IID 的记录。

我最初说我从多个表中收集信息的原因是,如果同一 IID 没有两条记录可用,FT_T 可能没有我需要的所有信息,所以我有从查询中的其他表JOINed 中检索它们。但是,我需要知道哪些FT_T.IIDFT_T 中有两条记录(或多于一条)。

【问题讨论】:

您能提供一些示例数据并期待结果吗? 【参考方案1】:

也许你需要计算join之前的计数和过滤:

SELECT . . .
FROM (SELECT F.*,
             COUNT(*) OVER (PARTITION BY F.IID) as IID_CNT
      FROM FT_T F
     ) JOIN
     CEMEI_T MCI
     ON F.IID = MCI.IID JOIN
     EDE_T EDE
     ON MCI.E_NUM = EDE.E_NUM JOIN
     EDIE_T EDIE
     ON EDIE.IID = F.IID AND EDIE.ET_ID = EDE.ET_ID
 . . .

【讨论】:

这是有道理的,但是,我刚刚意识到我的分区不仅应该超过F.IID,还应该是来自其他列的硬编码值,例如F.TYPE = 'A' 因为可能有多行具有相同的F.IID,但我应该只考虑窗口中带有F.TYPE='A' 的行。有没有办法在分区窗口中包含条件? 嗯......也许把它放在那个分区窗口子查询的 WHERE 子句中!但我想计数仍然会超过所有TYPE,不是吗? @NuCradle 。 . .只能回答你问的问题,问题是关于数F.IID【参考方案2】:

这只是评论/观察,但需要格式化

您将in(...)select distinctnot in(...,...) 一起使用似乎很复杂,如果某些值为NULL,则可能会出现问题。我建议您考虑改用 EXISTS 和 NOT EXISTS。例如

AND EXISTS (
    SELECT
        NULL
    FROM FT_T
    WHERE F.IID = FT_T.IID
    AND FT_T.GROUP_ID = 'BG'
    AND FT_T.DEL_F = 'N'
    AND NOT EXISTS (
        SELECT
            NULL
        FROM CEMEI_T
        WHERE FT_T.IID = CEMEI_T.IID
        AND FT_T.E_NUM = CEMEI_T.E_NUM
        AND CEMEI_T.TOS = 'BVVB'
        AND CEMEI_T.EFF_END_DT IS NULL
    )
)

【讨论】:

以上是关于如何在 Oracle 中使用分区获取记录计数的主要内容,如果未能解决你的问题,请参考以下文章

如何通过重复计数逻辑处理row_number分区中的空列?

如何在 SQL 中以高性能的方式使用 PARTITION BY 获取最新记录?

Oracle如何获取逗号分隔字符串中的出现次数

如何在动态 sql (ORACLE PLSQL) 中获取局部临时变量中的计数 (*) 值

如何在 hbase 表中获取计数记录?查询记录的最快方法是啥?

Oracle 查询:如何将返回的记录限制为计数 > 1 但显示完整结果的记录?