【问题标题】:ORACLE - How to count the total of two queries(with different WHERE clauses) from same table?ORACLE - 如何计算来自同一个表的两个查询(具有不同的 WHERE 子句)的总数?
【发布时间】:2019-02-07 17:48:04
【问题描述】:

我想捕获每个数字的聚合,但不确定如何从具有不同“WHERE”标准的几个查询(来自同一个表的所有数据)中收集所有结果。

例如,

第一个查询:

SELECT * FROM tbl
WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
AND tbl.send_date > TRUNC(SYSDATE) - 30
GROUP BY tbl.job_nbr;

第二次查询:

SELECT * FROM tbl
WHERE tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
AND tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')
AND tbl.send_date > TRUNC(SYSDATE) - 30
GROUP BY tbl.job_nbr;

我不确定仅使用 WHERE 子句是否满足我的要求

WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
AND tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
AND tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')

我感到困惑的是,我的第一个查询生成的结果不需要满足第二个查询的第一个 AND 运算符条件。似乎如果我将所有列出的值合并到 'tbl.from IN' 条件中并使用 AND 运算符('tbl.to IN'),则返回的结果将仅是 'tbl.from IN' 条件中列出的结果使用“tbl.to IN”列。

两个查询显然会产生单独的结果,但我想组合一组结果,以便我可以计算所有出现的次数,按唯一作业编号 (tbl.job_nbr) 分组。

*注意:我也有点担心性能,因为我想合并到更大的查询中。

我确信它很简单,或者至少有点简单,但我花了很多时间试图弄清楚这一点。如果有人愿意帮助我,我将不胜感激!

如果我解释得不够清楚或有人有其他问题,我会尽力澄清。

【问题讨论】:

    标签: sql oracle oracle11g


    【解决方案1】:

    我想你想要条件聚合:

    SELECT tbl.job_nbr,
           SUM(CASE WHEN tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
                   THEN 1 ELSE 0
               END) as cnt1,
           SUM(CASE WHEN tbl.from IN ('GGGB', 'GVCE', 'GMWA', 'GTYR') AND 
    AND tbl.to IN ('GGGBP2', 'GVCEP3', 'GMWAP1', 'GTYRP3')
                    THEN 1 ELSE 0
               END) as cnt2
    FROM tbl
    WHERE tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
    AND tbl.send_date > TRUNC(SYSDATE) - 30
    GROUP BY tbl.job_nbr;
    

    【讨论】:

    • 谢谢!我可以将这两个案例别名加在一起吗?
    • 您可以使用子查询来添加别名。
    【解决方案2】:

    使用case when,我的意思是条件聚合:

     select tbl.job_nbr, 
      sum(case when tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF') then 1 else 0 end) 
    as firstquery_count,
      sum(case when tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3' then 1 else 0 end) 
     as secondndtquery_count
     from tbl where tbl.send_date > TRUNC(SYSDATE) - 30
      group by tbl.job_nbr
    

    从 cmets 看来,您想同时添加两个计数,以便您可以使用 cte

    with cte as
    (
    select tbl.job_nbr, 
          sum(case when tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF') then 1 else 0 end) 
        as firstquery_count,
          sum(case when tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3' then 1 else 0 end) 
         as secondndtquery_count
         from tbl where tbl.send_date > TRUNC(SYSDATE) - 30
          group by tbl.job_nbr
    ) select job_nbr,firstquery_count+secondndtquery_count as total
       from cte
    

    但是使用 cte 你可以对第一个查询执行相同的操作,只需使用这两个计数的相加

    【讨论】:

    • 谢谢!我可以将这两个案例别名加在一起吗?
    • @ADOT 一起是什么意思?
    • 求和 firstquery_count 和 secondquery_count
    • @ADOT 是的,你可以
    • @ADOT answer eidted
    【解决方案3】:

    据我了解,您需要 1 个计数器,因此请将条件与 OR 结合起来:

    SELECT tbl.job_nbr, COUNT(*) counter FROM tbl 
    WHERE 
      tbl.send_date > TRUNC(SYSDATE) - 30
      AND 
      (
        tbl.from IN ('NIVA', 'TIRB', 'RIFG', 'PWDF')
        OR ( 
          tbl.from IN ('GGGB','GVCE','GMWA','GTYR')
          AND 
          tbl.to IN ('GGGBP2','GVCEP3','GMWAP1','GTYRP3')
        )
      )
    GROUP BY tbl.job_nbr;
    

    【讨论】:

    • 这实际上符合我的确切要求。谢谢你!我知道 WHERE 子句中的逻辑很简单。现在,如果我能让它运行得更快一点(没有创建索引或视图的权限)
    • 这些IN (...) 语句以效率低下着称,但我不知道如何避免它们
    • 来自oracle-base.com/articles/misc/short-circuit-evaluation-in-plsql,也许将日期条件放在首位会提高性能。我会编辑
    猜你喜欢
    • 1970-01-01
    • 2014-12-01
    • 2021-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-03
    • 2017-05-20
    相关资源
    最近更新 更多