djems54 Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 Bonjour, J'ai une table qui gère des tickets. Chaque ticket a une date de création (champ created) et une date de fermeture (champ closed). J'aimerai faire une requête me permettant d'afficher par jours, le nombre de tickets qui ont été créé, et le nombre qui ont été fermé. Je sais le faire en 2 requêtes. Est-ce possible de combiner les 2 en une seule et même requête ? pour avoir les 2 résultats en 1 seul. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fuinril Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 Alors oui c'est possible, mais fort peu logique. En gros tu as deux ensembles distincts et tu veux savoir combien de résultats tu as dans chaque ensemble. En théorie une requête sql sert à récupérer des données plus ou moins étendues se rapportant à un seul ensemble, donc si tu as plusieurs ensembles il faut faire deux requêtes. Explication avec la requête : select count(t1.created), count(t2.closed) from tickets as t1, tickets as t2 where t1.created='X' ans t2.created='Y' (Non je fais pas le tri par jour, c'est pas le but). Comme tu peux le constater il n'existe aucune liaison entre les deux tables, pas de jointures, les deux tables de bases sont donc complètement séparés. Ca revient donc au même de faire une ou deux requête, mais ton code sera plus claire et plus simple à lire si il y a 2 requêtes et puis c'est une bonne habitude à prendre, les requêtes sql tarabiscotées, limite incompréhensibles, c'est une plaie dans un projet et en plus ça n'apporte rien... Lien vers le commentaire Partager sur d’autres sites More sharing options...
djems54 Posté(e) le 15 juin 2011 Auteur Partager Posté(e) le 15 juin 2011 Voici mes 2 requêtes : SELECT DAY(created) AS d_created, MONTH(created) AS m_created, YEAR(created) AS y_created, count(*) AS nb_created FROM ticket GROUP BY YEAR(created), MONTH(created), DAY(created); SELECT DAY(closed) AS d_closed, MONTH(closed) AS m_closed, YEAR(closed) AS y_closed, count(*) AS nb_closed FROM ticket WHERE status="closed" GROUP BY YEAR(closed), MONTH(closed), DAY(closed); Qui me donne des résultats sous la forme : d_closed m_closed y_closed nb_closed 19 4 2011 1 21 4 2011 2 28 4 2011 1 29 4 2011 1 2 5 2011 3 3 5 2011 4 Même chose avec nb_created. J'aimerai avoir les 2 colonnes nb_created et nb_closed sur le même résultat. J'ai essayé la solution de Fuinril : SELECT count(t1.created), count(t2.closed) FROM ticket AS t1, ticket AS t2 WHERE t1.created BETWEEN "2011-04-29 00:00:00" AND "2011-04-29 23:59:59" AND t2.closed BETWEEN "2011-04-29 00:00:00" AND "2011-04-29 23:59:59" AND t2.status="closed" qui me donne un résultat de 2 et 2. Alors que le 29-04 il n'y en a qu'un seul de fermé... Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fuinril Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 Ah mais non ! Faut pas faire comme ça pour ce genre de requête. Après vérification mon exemple ne fonctionne pas, le moteur de mysql traite la requête de façon bizzare (il considère que les deux tables sont identiques et agit donc comme si il n'y en avait qu'une seule, même en essayant de le faire passer par des sous-requêtes...). J'aurai du vérifier avant, mais bon c'est de toutes façons clairement pas fait pour ça. Toujours est-il que tu veux 2 réponses (une réponse par ensemble), donc 2 lignes. Après le trier en plus par nombre de jours.... Sais pas faudrait voir si avec une clause en plus dans le group by... Essaye ça : SELECT count(status), status FROM ticket as t1 WHERE (created BETWEEN "2011-04-29 00:00:00" AND "2011-04-29 23:59:59" and status = 'open') or ( closed BETWEEN "2011-04-29 00:00:00" AND "2011-04-29 23:59:59" and status = 'closed') group by status Lien vers le commentaire Partager sur d’autres sites More sharing options...
djems54 Posté(e) le 15 juin 2011 Auteur Partager Posté(e) le 15 juin 2011 Le résultat est : Expr1 status 2 closed Sachant que dans ce cas précis (du 29-04), il y a 2 tickets créés, et 1 fermé. Ensuite, dans l'idéal, il faudrait que l'on ait pas besoin de rentrer une date précise, comme dans les 2 premières requêtes. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Fuinril Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 Pour avoir testé (cette fois ci) la requête, je peux t'assurer qu'elle fonctionne. Après a toi de voir si le status d'un ticket ouvert est bien renseigné à open, sinon mets autre chose (genre t1.status is NULL ou t1.status='')... Pour ta question, une requête du genre devrait convenir SELECT day, month, year, count(status), status FROM test as t1 group by DATE(created), DATE(closed), status C'est certainement pas parfait mais je doute que quelqu'un puisse faire mieux sans connaitre la structure de la table (qui m'a l'air ma foi particulière). En gros tu auras 2 lignes par jour avec le nombre de tickets fermés/ouverts. Lien vers le commentaire Partager sur d’autres sites More sharing options...
chaps Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 Hello ! Faire un bête "UNION" de tes deux requêtes ne répond pas à ton problème ? SELECT DAY(created) AS day, MONTH(created) AS month, YEAR(created) AS year, count(*) AS nb, 'created' AS status FROM ticket GROUP BY YEAR(created), MONTH(created), DAY(created); UNION SELECT DAY(closed) AS day, MONTH(closed) AS month, YEAR(closed) AS year, count(*) AS nb, 'closed' AS status FROM ticket WHERE status='closed' GROUP BY YEAR(closed), MONTH(closed), DAY(closed); Un truc du genre (je n'ai pas testé )... Lien vers le commentaire Partager sur d’autres sites More sharing options...
RING3R Posté(e) le 15 juin 2011 Partager Posté(e) le 15 juin 2011 la syntaxe que tu cherche est du genre: SELECT req1.nbouverts, req2.nbfermé FROM (SELECT count(ouverts) as nbouverts FROM tatable) as req1, <- Jointure naturelle (SELECT count(fermé) as nbfermé FROM tatable) as req2); enfin si j'ai bien compris ce que tu demande, j'ai eu recemment à faire une requete du genre et je m'en suis sorti comme ca Lien vers le commentaire Partager sur d’autres sites More sharing options...
BreizFenrir Posté(e) le 16 juin 2011 Partager Posté(e) le 16 juin 2011 Étant donné que ton champ status est vraisemblablement de type VARCHAR, il n'y a pas d'autre choix que d'utiliser deux requêtes distinctes ou deux sous-requêtes jointes par une UNION. Pour une seule requête je ne vois pas de cas où tu peux utiliser plusieurs fonctions d'agrégat où ces dernières doivent s'appliquer sur des enregistrements différents. Par contre, il reste possible de répondre à ton problème en une requête propre sous deux conditions : que ton champ status ne puisse avoir que 2 états possibles, et ton moteur de base de données fonctionne avec les valeurs booléennes de la même façon que MySQL. Si tel est effectivement le cas, et que tu as le contrôle sur le schéma de ta table, tu pourrais remplacer ce champ. Tu peux aussi, de manière transitoire, le garder. Pour la suite en tout cas, ajoute le champ suivant : `isClosed` TINYINT NOT NULL DEFAULT FALSE. Avec des valeurs correctes en table (les champs pour lequels status='closed' ont aussi isClosed=TRUE), la requête suivante devrait alors marcher : SELECT DAY(created) AS d_created, MONTH(created) AS m_created, YEAR(created) AS y_created, COUNT(*) AS nb_created, SUM(isClosed) AS nb_closed FROM ticket GROUP BY y_created, m_created, d_created; Lien vers le commentaire Partager sur d’autres sites More sharing options...
Yangzebul Posté(e) le 16 juin 2011 Partager Posté(e) le 16 juin 2011 Cela te sera probablement inutile car non implementé en mySQL, mais au cas ou tu sois sur un autre SGBD plus complet, je pense que tu devrai regarder du côté des WINDOW/PARTITION BY qui permettent de faire exactement ce que tu veux sans jongler avec des unions, requêtes imbriquées ou autres workaround à base de tables imbriquées. http://elegantcode.com/2009/01/04/sql-window-clause/ http://www.postgresql.org/docs/8.4/interactive/sql-expressions.html#SYNTAX-WINDOW-FUNCTIONS http://www.postgresql.org/docs/current/static/tutorial-window.html Lien vers le commentaire Partager sur d’autres sites More sharing options...
djems54 Posté(e) le 16 juin 2011 Auteur Partager Posté(e) le 16 juin 2011 Merci beaucoup pour toutes vos réponses ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.