1
votes

Compter le nombre de lignes dans une colonne par rapport à la date système ORACLE

J'ai une table avec une colonne appelée due_date qui définit quand un outil est dû. Je dois comparer cette valeur à la date système (sysdate) et compter le nombre de lignes remplissant certaines conditions.

Je dois:

Comptez le nombre de lignes avec des outils DUE (due_date> sysdate) ex- "tools_due" avec 50 lignes

Comptez le nombre de lignes d'outils qui ne sont PAS DUE (due_date

et

Comptez le nombre de lignes DUE TODAY (due_date = sysdate) ex- "tools_today" avec 10 lignes

ALORS, je dois prendre chaque décompte, comparer et stocker la condition avec le plus grand nombre de lignes. ex- "plus grand nombre"

Donc, dans cet exemple, tools_due a renvoyé 50 lignes, étant la plus élevée des 3, donc "high_count" serait égal à 50 ou "tools_due".

Comment pourrais-je faire cela? J'ai essayé d'utiliser un cas dans les clauses count mais je suis certain que je ne l'utilise pas correctement.

EDIT - J'ai oublié de mentionner que ma sortie DOIT afficher au moins une des chaînes que j'ai placées dans ces lignes de SGBD dans la capture d'écran. Mon mauvais mon mauvais.

Voici ce que j'ai jusqu'à présent: mon doodoocode


0 commentaires

5 Réponses :


0
votes

Je pense que vous voulez une logique comme celle-ci:

select sum(case when trunc(due_date) > trunc(sysdate + 1) then 1 else  0 end) as due_later,
       sum(case when trunc(due_date) = trunc(sysdate) then 1 else 0 end) as due_today,
       sum(case when trunc(due_date) < trunc(sysdate) then 1 else 0 end) as due_earlier
from . . .

Dans Oracle, sysdate a un composant de temps et cela pourrait vous décourager. De plus, le type de données date a un composant d'heure, que vous pourriez ne pas voir lorsque vous regardez la valeur.


3 commentaires

Y a-t-il une raison pour laquelle SUM serait meilleur que COUNT dans ce cas? J'ai vu la même chose dans d'autres articles, mais je n'ai vraiment vu la logique de personne derrière cela.


Count vous donnera également les résultats des autres parties, alors supprimez else ou utilisez sum ()


@Sweat à capuche . . . Vous demandez-vous pourquoi je préfère sum () ? La raison en est que count (1) = count (2) et je trouve cela un peu contre-intuitif. Lorsque vous utilisez sum () , ce que fait le code est assez clair: sum (1) <> sum (2) .



0
votes

Pour présenter le cas (non échu, échu, dû aujourd'hui) qui a le plus grand nombre, il est plus facile de traiter les lignes que les colonnes. Vous pouvez utiliser UNION ALL pour générer des enregistrements pour chacun des trois cas, puis trier les lignes par nombre et renvoyer uniquement l'enregistrement avec le plus grand nombre:

REASON  | CNT
:------ | --:
not due |   2

Démo sur DB Fiddle

Configuration:

| DUE_DATE            |
| :------------------ |
| 2019-10-10 22:10:43 |
| 2019-10-11 22:10:43 |
| 2019-10-12 22:10:43 |
| 2019-10-13 22:10:43 |

Résultats:

SELECT *
FROM (
    SELECT *
    FROM (
        SELECT 'due' reason, COUNT(*) cnt FROM mytable WHERE TRUNC(due_date) > TRUNC(sysdate)
        UNION ALL SELECT 'not due', COUNT(*) FROM mytable WHERE TRUNC(due_date) < TRUNC(sysdate)
        UNION ALL SELECT 'due today', COUNT(*) FROM mytable WHERE TRUNC(due_date) = TRUNC(sysdate)
    ) 
    ORDER BY cnt DESC
)
WHERE ROWNUM = 1


0 commentaires

0
votes

Comme le type de date a l'heure intégrée dans Oracle, utilisez donc trunc des deux côtés lors de la comparaison des dates pour tronquer la partie heure

    Trunc(column) = trunc(sysdate) 


0 commentaires

0
votes

Vous pouvez utiliser group by comme suit:

Select max(count(1)) from
(Select case when diff = 0 
             then 'due today'
             When diff < 0 then 'due'
             Else 'not due' end as status
 From
(Select trunc(due_date) - trunc(sysdate) as diff,
        Due_date 
  from your table))
Group by status;

Cheers !!


0 commentaires

0
votes

L'utilisation de TRUNC (due_date) empêchera Oracle d'utiliser un index le due_date colonne (vous auriez besoin d'un index basé sur la fonction à la place). Une alternative serait:

SELECT COUNT(
         CASE
         WHEN due_date >= TRUNC( SYSDATE ) + INTERVAL '1' DAY
         THEN due_date
         END
       ) AS tools_not_due_yet,
       COUNT(
         CASE
         WHEN due_date >= TRUNC( SYSDATE )
         AND  due_date <  TRUNC( SYSDATE ) + INTERVAL '1' DAY
         THEN due_date
         END
       ) AS tools_due_today,
       COUNT(
         CASE
         WHEN due_date <  TRUNC( SYSDATE )
         THEN due_date
         END
       ) AS tools_overdue
FROM   your_table


0 commentaires