0
votes

ORACLE - Comment compter le total de deux requêtes (avec des clauses WHERE différentes) de la même table?

Je souhaite capturer l'agrégat de chaque nombre, mais je ne sais pas comment rassembler tous les résultats de quelques requêtes (toutes les données de la même table) qui ont des critères «WHERE» différents.

Par exemple,

1ère requête:

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

2ème requête:

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;

I Je ne suis pas sûr que la simple utilisation d'une clause WHERE satisfasse mon exigence

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

Là où je suis confus, c'est que les résultats produits par ma première requête n'ont pas besoin de répondre à la première Condition d'opérateur AND de la 2ème requête. Il semble que si j'incorpore toutes mes valeurs répertoriées dans la condition 'tbl.from IN' et que j'utilise l'opérateur AND ('tbl.to IN'), les résultats renvoyés seront uniquement ceux répertoriés dans la condition 'tbl.from IN' avec la colonne 'tbl.to IN'.

Les deux requêtes produisent évidemment des résultats séparés, mais je veux combiner un ensemble de résultats afin de pouvoir compter toutes les occurrences, groupées PAR numéro de travail unique (tbl. job_nbr).

* Remarque: je suis également un peu préoccupé par les performances, car je souhaite l'incorporer dans une requête plus large.

Je suis sûr que c'est quelque chose de simple, ou du moins un peu simple, mais j'ai passé beaucoup de temps à essayer de comprendre cela. Si quelqu'un voulait bien m'aider, je l'apprécierais beaucoup!

Si je n'ai pas expliqué assez clairement ou si quelqu'un a des questions supplémentaires, je ferai de mon mieux pour clarifier.


0 commentaires

3 Réponses :


0
votes

Je pense que vous voulez une agrégation conditionnelle:

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 commentaires

Merci! Pourrais-je ajouter ces deux alias de cas ensemble?


Vous pouvez utiliser une sous-requête pour ajouter les alias.



0
votes

utilisez cas quand , je veux dire agrégation conditionnelle:

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

à partir des commentaires, il semble que vous voulez ajouter les deux comptes afin que vous puissiez utiliser cte

 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

mais en utilisant cte, vous pouvez faire la même chose avec la 1ère requête en ajoutant simplement ces deux nombres


5 commentaires

Merci! Pourrais-je ajouter ces deux alias de cas ensemble?


@ADOT signifie ensemble?


SUM firstquery_count et secondquery_count


@ADOT oui tu peux


Réponse @ADOT modifiée



0
votes

D'après ce que j'ai compris, vous avez besoin d'un compteur, alors combinez les conditions avec 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;


3 commentaires

Cela répond en fait à mon exigence exacte. Merci! Je savais que la logique de la clause WHERE était simple. Maintenant, si je peux le faire fonctionner un peu plus vite (pas de privilèges pour créer un index ou une vue)


Ces instructions IN (...) sont connues pour leur inefficacité, mais je ne vois pas comment vous pouvez les éviter


Depuis oracle-base.com/articles/misc/short-circuit -evaluation-in-pl‌ sql , peut-être mettre la condition de date en premier améliorerait les performances. Je vais éditer