Somme conditionnelle dans une requete sql

Résolu
Bonjour

J'ai une table du type
 	PAIS_1 	text 	utf8_general_ci 		Sí 	NULL 			
    NB_1 	int(11) 			Sí 	NULL 			
    PAIS_2 	text 	utf8_general_ci 		Sí 	NULL 			
    NB_2 	int(11) 			Sí 	NULL 			
    PAIS_3 	text 	utf8_general_ci 		Sí 	NULL
    NB_2 	int(11) 			Sí 	NULL 		



avec les données suivantes
date PAIS_1 NB_1 PAIS_2 NB_2 PAIS_3 NB_3
15/10/2020 ESPAGNE 15 ITALIE 10 IRLANDE 5
25/04/2020 ALLEMAGNE 20 ESPAGNE 15 IRLANDE 10
04/03/2021 FRANCE 30 ITALIE 24 ALLEMAGNE 20
10/10/2020 SUISSE 50 FRANCE 45 ESPAGNE 25
04/12/2021 ITALIE 30 IRLANDE 25 ALLEMAGNE 20

jE VOUDRAIS FAIRE LA SOMME DE NB.. PAR PAIS... ET PAR AÑO ORDONNEE DU PLUS GRAND VERS LE PLUS PETIT

JE VEUX DIRE
ANNEE COUNTRY_1 TOTAL_1 COUNTRY_2 TOTAL_2 COUNTRY_3 TOTAL_3
2020 ESPAGNE 55 FRANCE 45 IRLANDE 15
2021 ITALIE 54 ALLEMAGNE 40 FRANCE 30

quelqu'un pourrait-il me donner un coup de main pour cette requete? Merci d'avance.

13 réponses

  1. Modérateur
    Bonjour,

    Déjà, ta question concernant une requête SQL et non un problème de langage PHP... je la déplace dans le bon forum.

    Ensuite,
    Il va te falloir faire trois requêtes via l'instruction UNION
    Une par Pays/NB
    Pour ça, tu vas devoir utiliser l'instruction GROUP BY et la fonction SUM

    Je te laisse essayer ... et reviens nous montrer ce que tu auras tenté pour qu'on t'aide à corriger si besoin.

    0
    1. Voici la requete SQL pour obtenir les données.
      SELECT YEAR(DATE), PAIS_1 AS COUNTRY,NB_1 AS QU FROM camino
      UNION
      SELECT YEAR(DATE),PAIS_2 AS COUNTRY,NB_2 AS QU FROM camino
      UNION
      SELECT YEAR(DATE),PAIS_3 AS COUNTRY,NB_3  AS QU FROM camino )


      qui fonctionne bien en retournant tout les résultats.

      Comment faire pour faire la somme correspondante a chaque "pays" par année?

      J'ai essayer:
      SELECT COUNTRY, SUM(QU)  FROM (
      SELECT YEAR(DATE), PAIS_1 AS COUNTRY,NB_1 AS QU FROM camino
      UNION
      SELECT YEAR(DATE),PAIS_2 AS COUNTRY,NB_2 AS QU FROM camino
      UNION
      SELECT YEAR(DATE),PAIS_3 AS COUNTRY,NB_3  AS QU FROM camino )
      GROUP BY COUNTRY 
      

      mais cela ne marche pas.
      Je suppose que le problème vient de SELECT COUNTRY, SUM(QU) ... mais je ne sias pas comment le résoudre
      0
      1. Modérateur
        a somme correspondante a chaque "pays" par année

        GROUP BY COUNTRY , YEAR(DATE)
        
        0
    2. j'ai cette fait cela qui fonctionne bien
      SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAIS, SUM(RESUME.QU) AS TOTAL  FROM (
      SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY,NB_1 AS QU FROM camino
      UNION
      SELECT YEAR(DATE) AS D,PAIS_2 AS COUNTRY,NB_2 AS QU FROM camino
      UNION
      SELECT YEAR(DATE) AS D,PAIS_3 AS COUNTRY,NB_3  AS QU FROM camino ) AS RESUME
      GROUP BY ANNEE, PAIS 
      ORDER BY  ANNEE DESC, TOTAL DESC LIMIT 5
      


      J'ai un petit probleme avec ORDCER BY
      Je voudrai afficher pour chaque ANNEE les cinq plus grand Total.
      Dans ma requete le "LIMIT 5" s'applique a "ANNEE". Comment dois-je faire pour qu-il s'applique a TOTAL?
      Merci pour ton soutien.
      0
      1. Modérateur
        Tu n'as qu'à mettre un ORDER et LIMIT sur CHAQUE sous requête ( et le GROUP BY aussi sur chaque sous-requete dans ce cas.. )
        0
      2. Contributeur Ambassadeur
        si tu repars de ce que tu as fait en #4, et que tu le sauves en l'appelant "dani", je pense que tu dois faire ainsi pour obtenir le résultat attendu:
        SELECT d.annee, d.pays, d.total
        FROM dani as d
        WHERE d.annee & d.pays in (select top 5 annee & pays from dani
        where dani.annee = d.annee order by total desc)
        ORDER BY d.annee, d.total DESC;
        


        EDIT: ce que tu as fait en #4, sans le LIMIT.
        0
    3. J AI UNE ERREUR ·1064 AVEC CETTE REQUETE

      SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAIS, SUM(RESUME.QU) AS TOTAL  FROM (
      SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY,NB_1 AS QU FROM camino GRUUP BY D, COUNTRY ORDER BY D DESC, QU DESC LIMIT 5
      UNION
      SELECT YEAR(DATE) AS D, PAIS_2 AS COUNTRY,NB_2 AS QU FROM camino GROUP BY D, COUNTRY ORDER BY D DESC QU DESC LIMIT 5
      UNION
      SELECT YEAR(DATE) AS D, PAIS_3 AS COUNTRY,NB_3 AS QU FROM camino GROUP BY D, COUNTRY ORDER BY D DESC QU DESC LIMIT 5 ) AS RESUME
      
      0
      1. Contributeur Ambassadeur
        bonjour,
        Peux-tu partager le message d'erreur complet?
        As-tu testé séparément les sous-requêtes?
        Pourquoi as-tu supprimé le GROUP BY de la requête principale?
        0
    4. Bonjour yg_be

      Merci pour ton soutien.
      voici ma derniere requete qui fonctionne
      SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAIS, SUM(RESUME.QU) AS TOTAL  FROM (
      SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY,NB_1 AS QU FROM camino
      UNION
      SELECT YEAR(DATE) AS D,PAIS_2 AS COUNTRY,NB_2 AS QU FROM camino
      UNION
      SELECT YEAR(DATE) AS D,PAIS_3 AS COUNTRY,NB_3  AS QU FROM camino ) AS RESUME
      GROUP BY ANNEE, PAIS 
      ORDER BY  ANNEE DESC, TOTAL DESC
      


      Mais quand je veux extraire seulement les 5 plus grands résultats de QU, avec cette requette, j'obtient tout les résultat et non les 5 plus grands de chaqe année

      SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAIS, SUM(RESUME.QU) AS TOTAL  FROM (
      (SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY, NB_1 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
      UNION
      (SELECT YEAR(DATE) AS D,PAIS_2 AS COUNTRY, NB_2 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
      UNION
      (SELECT YEAR(DATE) AS D,PAIS_3 AS COUNTRY, NB_3  AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5) ) AS RESUME
      GROUP BY ANNEE, PAIS 
      ORDER BY  ANNEE DESC, TOTAL DESC 
      

      Je n'ai plus d'erreur
      0
      1. Opus je ne comprend pas ce que tu me dis:
        "si tu repars de ce que tu as fait en #4, et que tu le sauves en l'appelant "dani", je pense que tu dois faire ainsi pour obtenir le résultat attendu:"
        SELECT d.annee, d.pays, d.total
        FROM dani as d
        WHERE d.annee & d.pays in (select top 5 annee & pays from dani
        where dani.annee = d.annee order by total desc)
        ORDER BY d.annee, d.total DESC;


        Voici ce a quoi je suis arrivé qui ne limite pas a 5 le nombre de COUNTRY / TOTAL pour chaque ANNEE
        SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAIS, SUM(RESUME.QU) AS TOTAL  FROM (
        (SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY, NB_1 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
        UNION
        (SELECT YEAR(DATE) AS D,PAIS_2 AS COUNTRY, NB_2 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
        UNION
        (SELECT YEAR(DATE) AS D,PAIS_3 AS COUNTRY, NB_3  AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5) ) AS RESUME
        GROUP BY ANNEE, PAIS 
        ORDER BY  ANNEE DESC, TOTAL DESC 
        


        et je ne sais pas quoi faire avec ta requette.
        Peut-tu m'expliquer un peu plus?
        0
        1. Contributeur Ambassadeur
          Tu es arrivé à une requête qui te donne tous les résultats, et tu souhaites réutiliser cette requête et n'en garder que 5 par année.
          Pour cela, je suggère que tu crées une "view", ce qui permet de mémoriser et de nommer la requête, et d'ensuite la réutiliser un peu comme si c'était une table.
          exemple:
          CREATE VIEW dani AS
          SELECT RESUME.D AS ANNEE, RESUME.COUNTRY AS PAYS, SUM(RESUME.QU) AS TOTAL  FROM (
          (SELECT YEAR(DATE) AS D, PAIS_1 AS COUNTRY, NB_1 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
          UNION
          (SELECT YEAR(DATE) AS D,PAIS_2 AS COUNTRY, NB_2 AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5)
          UNION
          (SELECT YEAR(DATE) AS D,PAIS_3 AS COUNTRY, NB_3  AS QU FROM camino GROUP BY COUNTRY ORDER BY D DESC, QU DESC LIMIT 5) ) AS RESUME
          GROUP BY ANNEE, PAIS

          Ensuite, tu testes ma suggestion.
          0
      2. C'est tès bien et j'ai bien compris que je crée une nouvelle table.
        Mais en réalité j'ai fait une grosse erreur et je m'en excuse.
        Je m'explique:

        J'extrait mes données et j'obtient:
        ANNEE PAYS TOTAL
        2022 FRANCE 2155
        2022 ESPAGNE 1952
        2022 PORTUGAL 1854
        2022 SUISSE 1741
        2022 ITALIE 1562
        2022 USA 1322
        2022 JAPON 1100
        2021 ESPAGNE 2014 ect...

        alors que ce dont ja'i besoin c'est ce resultat:
        ANNEE PAYS_1 TOTAL_1 PAYS_2 TOTAL_2 PAYS_3 TOTAL_3 PAYS_4 TOTAL_4 PAYS_5 TOTAL_5
        2022 FRANCE 2155 ESPAGNE 1952 PORTUGAL 1854 SUISSE 1741 2 ITALIE 1562
        2021 ESPAGNE 2014 ect...

        DONC a partir d ela table créée je fait cette requette pour le plus grand TOTAL
        SELECT ANNEE, PAYS, MAX(TOTAL) AS PREM
          FROM resultat
         


        Et celle ci pour le second plus grand
        SELECT ANNEE, PAYS, MAX(TOTAL) AS PREM
          FROM resultat
         WHERE TOTAL < ( SELECT MAX( TOTAL)
                         FROM resultat 
                        )


        et ainsi de suite

        comment dois-je faire pour imbriquer ces requettes et obtenir le resultat souhaité ? Peux-tu me donner une ligne directrice.
        0
        1. Contributeur Ambassadeur
          peut-être:
          create view r1 as
          SELECT ANNEE, PAYS, MAX(TOTAL) AS PREM
            FROM resultat
           WHERE TOTAL < ( SELECT MAX( TOTAL)
                           FROM resultat 
                          )

          create view r2 as
           SELECT ANNEE, PAYS, MAX(TOTAL) AS PREM
            FROM resultat
           WHERE TOTAL < ( SELECT MAX( TOTAL)
                           FROM resultat 
                          )

          select r1.annee, r1.pays, r1.prem , r2.pays, r2.prem
          from r1 , r2
          where r1.annee = r2.annee
          0
      3. comme tu l'as vu, j'ai tenter une autre route pour obtenir mon tableau. parceque j'ai essayer en vain de l'obetenir avec des requettes.

        Je veux obtenir les 5 premiers resultat de chaque annee de ma table resultat
        Pour le premier pas de souci.

        pour le second, j'ai fait

        create view r2 as
         SELECT ANNEE, PAYS, MAX(TOTAL) AS PREM
          FROM resultat
         WHERE TOTAL < ( SELECT MAX( TOTAL)
                         FROM resultat 
                        )
                        GROUP BY ANNEE
                        ORDER BY ANNEE DESC


        Mais j'obtient :
        le premier de l'annee 2022
        le seconde de l'annee 2021
        le premier de l'annee 2022

        J'ai essayer d'autres requette mais en vain.

        Saurais-tu me dire ce que je dois faire?
        0
        1. Contributeur Ambassadeur
          As-tu essayé ma suggestion en #11?
          0
      4. Oui ma requette me donne

        ANNEE PAYS TOTAL
        2022 Argentina 1670
        2022 Japón 1499
        2022 Gabón 1463
        2022 Argelia 1380
        2022 Jamaica 1162
        2022 Haití 99
        2022 Ciudad del Vaticano 30
        2022 Albania 22
        2022 Laos 11
        2021 ES 3000
        2021 FR 2800
        2021 FRANCE 222
        2021 Tailandia 99
        2021 NULL 55
        2021 Haití 55
        2021 Japón 9
        2021 Argelia 5
        2021 0 0
        2020 Japón 453

        et je veux obtenir

        ANNEE PAIS 1 QU 1 PAIS 2 QU 2 PAIS 3 QU 3 PAIS 4 QU 4 PAIS 5 QU 5
        2022 ARGENTINA 1670 JAPON 1499 Gabón 1463 Argelia 1380 Jamaica 1162
        2021 ES 3000 FR 2800 FRANCE 222 Taillandia 99 Null 55
        2020 japon 453 THAIL 99 JAMAICA 55
        0
        1. Contributeur Ambassadeur
          c'est le résultat de la requête suggérée en #9?
          0
      5. Oui rangé dans une VIEW resultat.
        D'ailleurs j'ai utilisé lle même pricncipe de créé une VIEW pour extraire les plus grand resultat de chaque année
        CREATE VIEW top_1 AS
        	(SELECT ANNEE, PAYS, TOTAL 
             FROM resultat 
             WHERE TOTAL IN 
             	(SELECT MAX(TOTAL)) 
             GROUP BY ANNEE)
        


        et cela fonctionne.

        Mais pour obtenir le second plus grand avec cette requette c'est mon probleme.
        CREATE VIEW top_2 AS
        (SELECT ANNEE, PAYS, TOTAL 
             FROM resultat 
             WHERE TOTAL IN 
             	(SELECT MAX(TOTAL) 
                 WHERE TOTAL < 
                 	(SELECT MAX(TOTAL) FROM RESULTAT 
                    ) 
             GROUP BY ANNEE
             ORDER BY ANNEE DESC)

        j'obtient :
        le premier de l'annee 2022
        le seconde de l'annee 2021
        le premier de l'annee 2022
        0
        1. Contributeur Ambassadeur
          As-tu essayé ceci, suggéré le 6 juin 2022 à 17:24?
          SELECT d.annee, d.pays, d.total
          FROM resultat as d
          WHERE d.annee & d.pays in (select top 5 annee & pays from resultat as r
          where r.annee = d.annee order by total desc)
          ORDER BY d.annee, d.total DESC;
          0
      6. OUI ET J'AVAIS CETTE ERREUR

        #1064 - Algo está equivocado en su sintax cerca '5 ANNEE & PAYS from resultat as r
        where r.ANNEE = d.ANNEE order by TOTAL desc)
        ' en la linea 3
        0
        1. Contributeur Ambassadeur
          peut-être
          SELECT d.annee, d.pays, d.total
          FROM resultat as d
          WHERE d.annee & d.pays in (select annee & pays from resultat as r
          where r.annee = d.annee order by total desc limit 5)
          ORDER BY d.annee, d.total DESC;
          0
      7. Erreur #1235 - Esta versión de MySQL no soporta todavia 'LIMIT & IN/ALL/ANY/SOME subquery'

        J'ai la version mysql 5-7-36 et j'ai verifier sur le site de WAMPSERVEUR, il s'agit de la derniere version
        0
        1. Contributeur Ambassadeur
          Je ne vois pas d'autre façon d'obtenir le résultat directement via SQL.
          0
      8. C'est ce que je craignais, parceque ca fait un moment que je tourne en rond sans arriver à un resultat.

        Et je peux l'obtenir via des boucles php en suivant mon post de ce matin?
        0
        1. Contributeur Ambassadeur
          Oui, certainement. Tu clotures cette discussion?
          0