IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

Simuler boucle Foreach


Sujet :

Requêtes MySQL

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2017
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2017
    Messages : 38
    Points : 38
    Points
    38
    Par défaut Simuler boucle Foreach
    Bonjour,

    Pour ma première contribution à ce forum, j'aimerais avoir une solution pour simuler une boucle foreach dans une requête SQL.

    Voici le contexte, relativement simple soit dit en passant :
    J'ai une table avec des articles, des prix, et des dates de création du prix. La date est stockée en format nombre du type '20170101'.

    Un article possède plusieurs prix, mais un seul qui est celui actuel.

    J'aimerais trouver, pour chaque articles, le prix qu'il avait à une date donnée. Ce qui revient à dire, trouver pour chaque article, le prix dont la date de création est la plus proche inférieure à une date donnée.

    J'aimerais donc faire quelque chose du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT LIMIT 1 Article, Prix, DateCreation
    FROM Tarif
    WHERE DateCreation < 20170801
    ORDER BY DateCreation DESC
    Mais pour chaque article. Donc l'imbriquer dans une sorte de :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    FOREACH SELECT DISTINCT Article
    FROM Tarif
    ...
    Bien sûr ma syntaxe est incorrecte. Pouvez-vous m'aiguiller ?

    Merci.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 778
    Points
    30 778
    Par défaut
    Question mainte fois poséee
    Une réponse parmi d'autres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT  Article
        ,   Prix
        ,   DateCreation
    FROM    Tarif   AS trf
    WHERE   EXISTS
            (   SELECT  NULL
                FROM    Tarif   AS drn
                WHERE   drn.DateCreation < 20170801
                    AND drn.Article = trf.Article
                HAVING  MAX(drn.DateCreation)   = trf.DateCreation
            )
    ;
    Par ailleurs, pourquoi avoir enregistré les dates dans un type numérique alors qu'il existe un type date bien plus adapté ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2017
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2017
    Messages : 38
    Points : 38
    Points
    38
    Par défaut
    Je n'énumère plus les inepties que contient cette base de données malheureusement.

    En soit, vu l'usage que j'ai des champs date, qu'elles soient de type numérique n'est pas la plus grande tare de la DB j'en ai bien peur.

    A sa décharge, le logiciel qui manipule et crée cette DB est un dinosaure. Et à ma décharge, nous travaillons avec l'équipe informatique pour migrer la DB vers un environnement 100% relationnel qui garantit l'intégrité des données (et dont j'iamgine les dates seront au format date ^^). Mais pour l'instant je travaille toujours sur la vieille.

    Quoi qu'il en soit merci pour ton astuce. Je m'empresse de la tester en 'grandeur nature'.

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2017
    Messages
    38
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Belgique

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Bâtiment

    Informations forums :
    Inscription : Août 2017
    Messages : 38
    Points : 38
    Points
    38
    Par défaut
    Hum, je pense que j'ai été un peu trop réduit mon problème pour la clarté de mon explication. Il apparaît qu'il est plus complexe et que la date maximum n'est pas fixe mais dépend d'une ligne à l'autre.
    Je n'arrive pas à transposer ta solution à mon cas. Je m'explique.

    En fait, il y a deux tables à utiliser :
    • CS (table qui reprend les conditions spéciales des clients, qui ont droit à un prix réduit sur des articles). On y retrouve entre autres les champs :
      • CodeArticle (article sur lequel s'applique la condition spéciale)
      • CodeClient (client qui a droit à la CS)
      • DateDebut (date à partir de laquelle la CS est applicable au client)
      • DateFin (date à partir de laquelle le client ne bénéficie plus de la CS)
      • PrixHT (prix hors taxe de l'article sous cette condition spéciale)
      • QteMin (quantité d'achat minimum à partir de laquelle la CS est applicable)
      • Societe (ensemble des magasins dans lesquels la CS est applicable au client)
      • FlagActif (booléen qui détermine si la CS est toujours applicable)
      • FlagSuppr (booléen qui renseigne si la CS a été supprimée ou non)
    • Tarif (table qui reprend les prix des différents articles). On y retrouve entre autres les champs :
      • CodeArticle
      • PRR (Prix de revient réel, en gros c'est notre prix d'achat auprès du fournisseur)
      • CodeDepot (magasin sur lequel le tarif s'applique. Tous les articles ont une ligne avec un code dépôt = 0 qui est le prix par défaut pour tous les magasins)
      • TarifActuel (booléen qui détermine si le tarif est en en cours)
      • DateTarif (date de création du tarif, toujours au format numérique)
      • PrixHT (Prix de vente hors taxe)


    Nos tarifs évoluent et nos prix d'achat et de ventes peuvent augmenter. On a remarqué que les conditions spéciales ne suivaient pas cette évolution. Il m'a donc été demandé de trouver les CS qui engendraient une vente à perte.
    Pour se faire, j'ai procédé ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    SELECT 
    CS.CodeArticle, 
    CS.CodeClient, 
    CS.DateDébut, 
    CS.DateFin, 
    CS.PrixHT, 
    CS.QteMinimum, 
    CS.Societe, 
    Tarif.PRR, 
    Tarif.CodeDepôt
     
    FROM 
    CS, 
    Tarif
     
    WHERE
    Tarif.CodeArticle = CSP.CodeArticle
     
    AND CS.Societe = 10
    AND (Tarif.CodeDepôt = 0
    	OR Tarif.CodeDepôt = 6
    	OR Tarif.CodeDepôt = 14)
    AND Tarif.TarifActuel = 1
    AND CS.PrixHT < Tarif.PRR
    AND CS.FlagActif = 1
    AND CS.FlagSuppr = 0
    Je procède société par société et la société 10 ici comprend les magasin 6 et 14. Et je sélectionne les CS pour lesquels le prixHT est inférieur au Prix d'achat (PRR) actuel.

    Très bien, sauf que maintenant, j'aimerais, non plus le PRR actuel, mais le PRR de l'époque de la création de la CS, afin d'identifier le pourcentage de marge que l'on faisait sur ces ventes en CS à leur création et réappliquer ces marges sur les CS.

    D'où l'idée d'une requête qui extrait pour chaque CS sélectionnée le PRR de l'époque, c'est à dire celui dont la DateTarif est le plus proche inférieur à la DateDebut de la CS.

    J'espère avoir été clair.

    Je n'ai pas réussi à transposer l'exemple à cette requête. Pas encore un expert en syntaxe SQL.

    Merci.

Discussions similaires

  1. [JSTL] boucle forEach pour deux liste en même temps
    Par ruud002 dans le forum Taglibs
    Réponses: 1
    Dernier message: 28/09/2006, 16h54
  2. [Tableaux] Boucle foreach inbriquée
    Par nebil dans le forum Langage
    Réponses: 17
    Dernier message: 10/09/2006, 12h40
  3. [C# VS 2005] Collection et boucle foreach
    Par SDragon dans le forum Windows Forms
    Réponses: 3
    Dernier message: 24/07/2006, 20h43
  4. [C# 1.1]Boucles foreach imbriquees
    Par Nip dans le forum Windows Forms
    Réponses: 12
    Dernier message: 13/04/2006, 17h35
  5. [Tableaux] la boucle foreach
    Par jeanfrancois dans le forum Langage
    Réponses: 7
    Dernier message: 09/03/2006, 18h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo