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
5 Réponses :
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.
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)
.
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
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
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)
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 !!
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