0 votes

Comment obtenir des agrégats sans utiliser une requête sql imbriquée ?

J'écris un rapport personnalisé à partir d'une base de données Avamar (Postgresql) qui contient l'historique des tâches de sauvegarde. Ma tâche consiste à afficher les tâches qui ont échoué la nuit dernière (en fonction du code d'état) et à inclure le taux de réussite de ce client (tâches réussies/total des tâches exécutées) au cours des 30 derniers jours sur la même ligne.

Ainsi, la sélection globale ne retient que les clients qui ont échoué (status_code n'est pas égal à 30000, qui est le code de réussite). Cependant, pour chaque client qui a échoué la nuit dernière, j'ai également besoin de savoir combien de travaux ont réussi, et combien de travaux ont été lancés/planifiés au cours des 30 derniers jours. (La partie période de temps est simple, donc je ne l'ai pas incluse dans le code ci-dessous, pour rester simple).

J'ai essayé de faire cela sans utiliser de requête imbriquée, en me basant sur les commentaires de Hobodave sur cette question similaire mais je ne suis pas tout à fait capable d'y arriver.

Dans la requête ci-dessous, j'obtiens l'erreur suivante : column "v_activities_2.client_name" must appear in the GROUP BY clause or be used in an aggregate function

Voici ma requête (cassée). Je sais que la logique est imparfaite, mais je n'arrive pas à trouver la meilleure façon d'y parvenir. Merci d'avance pour tout conseil !

select
  split_part(client_name,'.',1) as client_name,
  bunchofothercolumnns,
  round(
    100.0 * (
      ((sum(CASE WHEN status_code=30000 THEN 1 ELSE 0 END))) /
      ((sum(CASE WHEN type='Scheduled Backup' THEN 1 ELSE 0 END))))
    as percent_total
from v_activities_2
  where
    status_code<>30000
  order by client_name

1voto

OMG Ponies Points 144785

Vous devez définir un GROUP BY si vous avez des colonnes dans le SELECT qui n'ont pas d'utilité. no sont soumis à des fonctions d'agrégation :

  SELECT SPLIT_PART(t.client_name, '.', 1) AS client_name,
         SUM(CASE WHEN status_code = 30000 THEN 1 ELSE 0 END) as successes
    FROM v_activities_2
GROUP BY SPLIT_PART(t.client_name, '.', 1)
ORDER BY client_name

Comment voulez-vous que cela fonctionne ?

      SUM(CASE WHEN status_code = 30000 THEN 1 ELSE 0 END) as successes
 FROM v_activities_2
WHERE status_code <> 30000

Tu ne peux pas t'attendre à compter les rangs que tu es à l'exclusion de .

0voto

filiprem Points 218

Pourquoi éviter les requêtes imbriquées ?

Cela semble être la solution la plus logique et la plus efficace.

Si vous effectuez cette opération en une seule fois, sans requêtes supplémentaires (uniquement des group by), vous finirez par analyser l'ensemble de la table (ou des tables jointes), ce qui n'est pas efficace, car seuls CERTAINS clients ont échoué la nuit dernière.

Les sous-requêtes ne sont pas si mauvaises, en général.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X