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

Langage SQL Discussion :

Insérer un Case dans une clause Where / Between?


Sujet :

Langage SQL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut Insérer un Case dans une clause Where / Between?
    Bonjour,

    J'explique un peu mon cas, je suis en train de travailler sur un rapport (qui forcément s'appuie sur une belle requête SQL, sinon le sujet serait au mauvais endroit).
    Ce rapport va avoir des paramètres qui devront avoir chacun une valeur unique : le grammage papier (qui ne me pose pas de problème actuellement), un nom de machine (qui est le paramètre compliquant de la requête), une date de début, une date de fin.

    Mon nom de machine aura donc une valeur unique mais va à la fois correspondre (parce que je dois piocher mes infos dans plusieurs tables différentes) à un nvarchar(50) (j'ai déjà eu des soucis de typage de mon paramètre dans une version simplifiée de la requête) dans une table ET à un int (l'ID de la machine) dans une autre table.
    Je n'ai pour le moment pas de table qui me permet de faire la correspondance entre le nvarchar(50) et l'int, sinon c'était un "non_sujet" puisque j'aurais ajouté une jointure supplémentaire à la requête.

    Pour pallier à ça, j'aurais bien ajouté dans les clauses WHERE un CASE, mais voilà ce que ça donnerait (en gros) :
    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
     
    SELECT 'mes colonnes'
    FROM 'mes tables'
    WHERE EXISTS (SELECT 'un id'
                            FROM 'une table'
                            WHERE 'id commande' = 'id de commande de la requête principale'
                            AND Grammage = @Gram -- où @Gram est mon 1er paramètre)
    AND (CASE WHEN @Machine = 'Cas1' -- où @Machine est le Nom de machine
                      (SELECT 'date de début'
                       FROM 'une autre table'
                       WHERE 'id machine' = 'mon int1') BETWEEN @Debut AND @ Fin -- où @Debut et @Fin sont les dates de début et de fin passées en paramètres
                      WHEN @Machine = 'Cas2'
                      (SELECT 'date de début'
                       FROM 'une autre table'
                       WHERE 'id machine' = 'mon int2)' BETWEEN @Debut AND @ Fin
                      END)
    Est-ce que c'est une forme "acceptable" d'un point de vue du serveur SQL (MS SQL Server pour la précision)?
    Est-ce qu'en termes de performances ça ne va pas "surcharger" le serveur (je sais que le rapport est voué à être généré tous les jours, donc le but n'est pas que le serveur mette 8h à le générer, il aura bien d'autres demandes dans sa journée!)?
    Et, n'étant pas un crack en administration des BDD ni un champion de la programmation, j'ai aussi un peu peur que cette manière de procéder soit un peu "crade", est-ce que vous voyez des optimisations possibles sur la requête? (je ne peux pas toucher à la conception des BDD, c'est utilisé par un ERP d'un éditeur donc pas question d'y mettre le bazar).

    Merci d'avance pour vos réponses

  2. #2
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 856
    Points : 1 641
    Points
    1 641
    Par défaut
    Bonjour,

    Si je comprends le problème on a des tables qui comportent les colonnes suivantes:
    * T1 : {id, id_commande, grammage}
    * T2 : {id_machine, date_debut}

    et le résultat attendu est un tableau de valeur distinctes des colonnes suivantes : {grammage papier, un nom de machine, une date de début, une date de fin}

    Je pense qu'il faille trouver une ou plusieurs tables qui permettent de faire un "cheminement' entre T1 (la commande ?) et T2 (l'impression d'un lot?)
    Par exemple une table T3 (planification de prod ?) qui comporte à la fois id_commande et id_machine.
    Le savoir est une nourriture qui exige des efforts.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Bonjour Michel,

    Le schéma de la BDD est encore plus corsé que ça, il comprend pas moins de 8 bases de données qui ont chacune un nombre variable de tables (la base des commandes contient plus de 80 tables, on dépasse les 70 pour le planning...) : un joyeux m**dier
    Et je n'ai pas le schéma complet de la BDD, donc j'ai plus de chances de gagner à l'Euromillions (sans y jouer) que de trouver les tables qui font le cheminement complet.
    Par exemple, une table qui recense les machines dans la base planning, mais qui ne dit pas si ces machines sont encore en service (et bien sûr, nous avons des machines qui ne sont plus en service, sinon je ne donnerais pas ce niveau de détail). (bis)

    Quoi qu'il en soit, merci déjà de m'avoir répondu.
    En parallèle j'ai tâtonné (beaucoup) de mon côté, et j'ai peut-être un début de solution (que je suis en train de tenter de confirmer avec les données que je vois dans l'ERP et en modifiant manuellement mes paramètres pour le moment).
    La bonne méthode serait donc de mettre dans la clause :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- Je passe le SELECT et le FROM --
    WHERE (CASE WHEN @Machine = 'Cas1' THEN (SELECT t1.Start --où Start est la date de début dans 'ma table'
                                                                         FROM 'ma table' t1
                                                                         WHERE t1.ID = 'lien avec une table de la requête principale' AND t1.IDMachine = 'id de @Machine1')
                         WHEN @Machine = 'Cas2' THEN (SELECT t2.Start 
                                                                         FROM 'ma table' t2
                                                                         WHERE t1.ID = 'lien avec une table de la requête principale' AND t1.IDMachine = 'id de @Machine2')
                         END) BETWEEN @Debut AND @Fin
    -- Et si besoin de GROUP BY ou ORDER BY on peut en mettre là --
    Le but du forum étant l'entraide, je note mes avancées, avec l'espoir que ça puisse servir à d'autres un jour.
    S'il existe une méthode plus "propre", je suis preneur aussi, ça ne peut pas faire de mal d'optimiser un peu une requête (même si actuellement la mienne s'exécute en moins d'une seconde, je ne peux pas généraliser).

  4. #4
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 922
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 922
    Points : 51 719
    Points
    51 719
    Billets dans le blog
    6
    Par défaut
    Ce serait pas plus simple comme cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    SELECT * 
    FROM   T
           JOIN 'ma table' AS MT
              ON t1.ID = 'lien avec une table de la requête principale' 
                 AND t1.IDMachine = 'id de @Machine1'
                 AND CASE WHEN @Machine = 'Cas1' THEN t1.Start
                          WHEN @Machine = 'Cas2' THEN t2.Start END BETWEEN @Debut AND @Fin
    ???

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  5. #5
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Peut-être, il faudra que j'essaie
    J'ai d'autres points à modifier sur ma requête pour affiner les données affichées par rapport à ce qui est renseigné dans la BDD, mais ça risque de devoir attendre demain pour que je puisse m'y pencher

    Je ferai un retour quand j'aurai pu comparer les deux façons de faire (même si je m'attends à ce que la méthode que j'ai trouvé soit moins performante, à mon avis on n'a pas tout à fait le même niveau d'expérience )

  6. #6
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 856
    Points : 1 641
    Points
    1 641
    Par défaut
    Citation Envoyé par Sylv_62 Voir le message
    Le schéma de la BDD est encore plus corsé que ça, il comprend pas moins de 8 bases de données qui ont chacune un nombre variable de tables (la base des commandes contient plus de 80 tables, on dépasse les 70 pour le planning...) : un joyeux m**dier
    Et je n'ai pas le schéma complet de la BDD, donc j'ai plus de chances de gagner à l'Euromillions (sans y jouer) que de trouver les tables qui font le cheminement complet.
    L'absence des contraintes de FK dans les bases est une stupidité sans nom.

    Dans ces cas là j'utilise une recherche sur les colonnes qui ont le même nom et le même type dans les différentes tables.
    Et je passe du temps à formaliser ça dans un schéma.

    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
    with 
    c_doublon as
    	(select name,user_type_id, count(*) as nb
    	from sys.columns
    	group by name,user_type_id
    	having count(*) >1
    	)
    select c.name as column_name,c.column_id,c.user_type_id,t.name as column_type, c.object_id, o.name as table_name
    from c_doublon cd
    	inner join sys.columns c on c.name=cd.name and c.user_type_id=cd.user_type_id
    	inner join sys.objects o on o.object_id=c.object_id and o.type = 'U'
    	left join sys.types t on t.user_type_id=c.user_type_id
    where 1=1
    	and c.name like '%id%'
    Order by column_name,table_name
    Le savoir est une nourriture qui exige des efforts.

  7. #7
    Membre expérimenté
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Septembre 2016
    Messages
    856
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2016
    Messages : 856
    Points : 1 641
    Points
    1 641
    Par défaut
    re,

    Autre solution : capturer les instructions SQL (profiler = plus simple ; évènement étendu = moins impactant) qui sont lancées par le logiciel.

    Une fois la trace capturée, une recherche sur le mot clé JOIN permettra d'espérer retrouver "ce qui se fait"
    Le savoir est une nourriture qui exige des efforts.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    L'absence des contraintes de FK dans les bases est une stupidité sans nom.

    Dans ces cas là j'utilise une recherche sur les colonnes qui ont le même nom et le même type dans les différentes tables.
    Et je passe du temps à formaliser ça dans un schéma.
    Pour le type, j'espère que les développeurs responsables du produit chez l'éditeur ont gardé le même...
    Mais j'ai déjà vu 2-3 tables où le nom est changé pour la clé étrangère

    Cependant, sur le fond, je suis d'accord, j'aurais bien aimé que ça soit un peu formalisé

    Dans un monde idéal, je me dégagerais du temps pour recréer un schéma consistant et complet.
    Mais le fait est que ça sort bien fort de mon périmètre (c'est l'éditeur qui est censé connaître le schéma, et il ne nous donnera pas le schéma complet) et que ça me prendrait bien trop de temps au vu du nombre de bases et de tables.
    Mon employeur me demandant d'autres choses, j'abandonne d'avance l'idée de mettre du "carburant" sur cette schématisation totale (peut-être que je m'y repencherai à un moment d'activité plus creuse).

  9. #9
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Michel.Priori Voir le message
    re,

    Autre solution : capturer les instructions SQL (profiler = plus simple ; évènement étendu = moins impactant) qui sont lancées par le logiciel.

    Une fois la trace capturée, une recherche sur le mot clé JOIN permettra d'espérer retrouver "ce qui se fait"

    Pourquoi j'ai pas pensé plus tôt aux outils de SQL Server pour pouvoir récupérer les requêtes lancées par le logiciel?
    Idée à creuser, merci du rappel.

    Je pense qu'on va trouver un bon gros paquet de requêtes impliquant un JOIN (presque toutes, en fait!), mais en analysant ces requêtes je pourrais trouver mon bonheur

  10. #10
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 922
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 922
    Points : 51 719
    Points
    51 719
    Billets dans le blog
    6
    Par défaut
    Citation Envoyé par Sylv_62 Voir le message
    ...
    Mais le fait est que ça sort bien fort de mon périmètre (c'est l'éditeur qui est censé connaître le schéma, et il ne nous donnera pas le schéma complet) et que ça me prendrait bien trop de temps au vu du nombre de bases et de tables.
    Mon employeur me demandant d'autres choses, j'abandonne d'avance l'idée de mettre du "carburant" sur cette schématisation totale (peut-être que je m'y repencherai à un moment d'activité plus creuse).
    Il existe des outils pour ça comme Power AMC de Sybase qui permet de faire une rétro ingénierie... 15 jours d'essais gratuit...

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  11. #11
    Membre à l'essai
    Homme Profil pro
    Administrateur systèmes et réseaux
    Inscrit en
    Septembre 2024
    Messages
    20
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Administrateur systèmes et réseaux

    Informations forums :
    Inscription : Septembre 2024
    Messages : 20
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par SQLpro Voir le message
    Il existe des outils pour ça comme Power AMC de Sybase qui permet de faire une rétro ingénierie... 15 jours d'essais gratuit...
    Merci pour le tuyau, ça peut valoir le coup de tester

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [11gR2] Case dans une clause where avec plusiuers valeurs à évaluer
    Par Oncle_Pete dans le forum SQL
    Réponses: 8
    Dernier message: 21/06/2018, 14h07
  2. Utiliser un alias de colonne dans une clause Where MS SQL
    Par sir dragorn dans le forum Langage SQL
    Réponses: 11
    Dernier message: 12/10/2011, 10h31
  3. Case dans une clause where
    Par Blaede dans le forum Langage SQL
    Réponses: 9
    Dernier message: 10/08/2009, 17h09
  4. fonction booleenne dans une clause where ?
    Par user_h dans le forum Oracle
    Réponses: 1
    Dernier message: 20/10/2005, 16h05

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