1. #1
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 164
    Points : 82
    Points
    82

    Par défaut Récupérer une partie d'un champ

    Bonjour,

    J'ai un petit souci sur SQL, qui j'imagine pour certains une juste banalité mais pour moi c'est compliqué !

    J'ai un champ Profil avec comme valeurs :

    A
    A-B
    A-C-D-A-B
    B-D
    D-D-C
    A-B-A
    etc...

    Je souhaite récupérer uniquement les profils avec A et B mais sans les autres soit A, A-B, A-B-A

    J'ai essayé avec un Substr, mais cela ne donne pas ce que je veux.

    Je suis actuellement sur uen requête qui fonctionne mais qui est trop brutale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    where profil NOT LIKE ('%C%') AND profil NOT LIKE ('%D%') AND profil NOT LIKE ('%E%')
    AND profil NOT LIKE ('%F%')....
    Avec autant de profil disponible, ce qui dans le temps n'est pas complet puisque un profil pourrait arriver et ma requête ne fonctionnera plus...

    Merci pour votre aide.

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Ingénieur d'études décisionnel
    Inscrit en
    mai 2002
    Messages
    7 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 7 283
    Points : 22 015
    Points
    22 015

    Par défaut

    C'est ce qui arrive quand un besoin est mal modélisé

    Il aurait fallu créer une table fille, avec une ligne pour chaque valeur associée à un profil.
    La requête aurait alors été extrêmement simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT  *
    FROM    profil  AS prf
    WHERE   NOT EXISTS
            (   SELECT  NULL
                FROM    valeurs_profil  AS vlr
                WHERE   vlr.id_profil   = prf.id_profil
                    AND id_valeur   NOT IN ('A', 'B')
            )
    ;
    Là, dans votre modèle, la recherche est complexe, l'ajout d'une valeur à un profil difficile, le retrait d'une valeur à un profil encore plus...
    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
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    2 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : février 2010
    Messages : 2 967
    Points : 4 896
    Points
    4 896
    Billets dans le blog
    1

    Par défaut

    Votre modèle des données est ma conçu.
    Cette colonne devrait être une table à part entière.

    Si c'est possible, corrigez ça, et vous n'aurez plus de problème.

    Alternative : passer par un SPLIT (non standard).

    Vous trouverez à cette adresse un exemple pour faire une telle fonction pour SQL Server en langage CLR.
    Avec Oracle, on peut faire la même chose en Java.

    Avec les autres (mais aussi SQL Server et Oracle) on peut s'en sortir aussi soit en détournant des fonctionnalités qui n'ont rien à voir (je trouve ça sale), soit en passant par des fonction stockées écrites en T-SQL/PL-SQL, etc.

    https://www.developpez.net/forums/d1...utilisant-clr/
    On ne jouit bien que de ce qu’on partage.

  4. #4
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 496
    Points
    39 496
    Billets dans le blog
    1

    Par défaut

    Vous violez la première forme normale... ! Et donc vous êtes dans la merde.... C'est qui arrive quand on respecte pas les règles du code de la route pardon de la modélisation !

    Je n'ose pas imaginer la suite de l'architecture de la base au sujet des formes normales suivantes :
    • 2 FN
    • 3 FN
    • FN de Boyce Codd
    • 4 FN
    • 5 FN
    • FN domaine clef
    • 6 FN

    ...

    Conclusion : formez vous à la modélisation et repectez au moins les 3 premières formanes normales !

    Pour la une : https://fr.wikipedia.org/wiki/Forme_..._forme_normale

    Et pour apprendre à modéliser et vous éviter des requêtes merdiques et des performances catastrophiques :
    Nom : Soutou Brouard Modélisation bases de données.jpg
Affichages : 43
Taille : 40,3 Ko

    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 164
    Points : 82
    Points
    82

    Par défaut

    Hop hop on va se calmer, qui vous a dit que j'avais modélisé ? Je ne suis pas le créateur du modèle relationnel et encore moins de l'architecture.

    Alors ce que je conseille à SQLpro un livre afin d'eviter d'agresser les gens :

    Nom : Le-savoir-vivre.jpg
Affichages : 43
Taille : 21,9 Ko

    Pour les autres merci à vous, je vais essayer de me débrouiller avec un SPLIT, je continue mes recherches.

  6. #6
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 496
    Points
    39 496
    Billets dans le blog
    1

    Par défaut

    C'est pas parce qu'une base de données est mal foutue, que vous ne devez pas tenter d'y remédier. Cette modélisation inepte posera des problèmes de plus en plus complexe et sera à l'origine de performances lamentables...

    En sus des conseils déjà donné il est possible de renormaliser une telle table par le biais d'une simple requête récursive.

    Comme vous n'avez pas respecté la charte de postage https://www.developpez.net/forums/a6...gage-sql-lire/ je vous donne un exemple sur une table bidon en SQL normatif :

    la table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE MaTable (Clef INT IDENTITY, Profil VARCHAR(1024));
     
    INSERT INTO MaTable VALUES
    ('A'),
    ('A-B'),
    ('A-C-D-A-B'),
    ('B-D'),
    ('D-D-C'),
    ('A-B-A');
    La requête :
    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
    WITH 
    T0 AS
    (SELECT Clef, 1 AS Ligne,
            CASE WHEN POSITION('-', Profil) > 0 THEN LEFT(Profil, POSITION('-', Profil) - 1) ELSE Profil END AS Profil1,
            CASE WHEN POSITION('-', Profil) > 0 THEN RIGHT(Profil, CHARACTER_LENGTH(Profil) - POSITION('-', Profil)) ELSE '' END AS ProfilN
     FROM   MaTable
     UNION ALL
     SELECT Clef, Ligne + 1,
            CASE WHEN POSITION('-', ProfilN) > 0 THEN LEFT(ProfilN, POSITION('-', ProfilN) - 1) ELSE ProfilN END AS Profil1,
            CASE WHEN POSITION('-', ProfilN) > 0 THEN RIGHT(ProfilN, CHARACTER_LENGTH(ProfilN) - POSITION('-', ProfilN)) ELSE '' END AS ProfilN
     FROM   T0
     WHERE  ProfilN <> '' 
    )
    SELECT Clef, Profil1, Ligne 
    FROM T0
    ORDER BY Clef, Ligne
    Le résultat :
    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
    Clef        Profil1   Ligne
    ----------- --------- -----------
    1           A         1
    2           A         1
    2           B         2
    3           A         1
    3           C         2
    3           D         3
    3           A         4
    3           B         5
    4           B         1
    4           D         2
    5           D         1
    5           D         2
    5           C         3
    6           A         1
    6           B         2
    6           A         3
    Il devient alors simplissime de trouver les éléments que vous souhaitez...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM   CeResultat
    WHERE  Profil1 IN ('A', 'B')
    GROUP  BY Clef
    HAVING COUNT(DISTINCT Profil1) >= 2;
    Merci à l'avenir de respecter la charte de postage !

    Et pour apprendre le langage SQL, rien ne vaut mon site : http://sqlpro.developpez.com/
    Comme mon livre : Nom : Couverture SQL Synthex 4e ed - 500.jpg
Affichages : 39
Taille : 77,8 Ko

    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  7. #7
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 496
    Points
    39 496
    Billets dans le blog
    1

    Par défaut

    Si vous aviez respecté la charte de postage, on aurait pu vous donner quelques chose de plus pertinent. Par exemple pour SQL Server v 2016 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT Clef, "value"
    FROM   MaTable 
           CROSS APPLY string_split(Profil, '-');
    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  8. #8
    Expert confirmé
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    février 2010
    Messages
    2 967
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Rhône (Rhône Alpes)

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

    Informations forums :
    Inscription : février 2010
    Messages : 2 967
    Points : 4 896
    Points
    4 896
    Billets dans le blog
    1

    Par défaut

    Tiens ? Split est intégré dans SQL Server 2016 ?
    On ne jouit bien que de ce qu’on partage.

  9. #9
    Rédacteur
    Avatar de SQLpro
    Homme Profil pro
    Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Inscrit en
    mai 2002
    Messages
    17 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert SGBDR & SQL, spécialiste Microsoft SQL Server
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 17 013
    Points : 39 496
    Points
    39 496
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par StringBuilder Voir le message
    Tiens ? Split est intégré dans SQL Server 2016 ?
    yes !!!!
    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...
    * * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    janvier 2006
    Messages
    164
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : janvier 2006
    Messages : 164
    Points : 82
    Points
    82

    Par défaut

    Citation Envoyé par SQLpro Voir le message
    C'est pas parce qu'une base de données est mal foutue, que vous ne devez pas tenter d'y remédier. Cette modélisation inepte posera des problèmes de plus en plus complexe et sera à l'origine de performances lamentables...

    En sus des conseils déjà donné il est possible de renormaliser une telle table par le biais d'une simple requête récursive.

    Comme vous n'avez pas respecté la charte de postage https://www.developpez.net/forums/a6...gage-sql-lire/ je vous donne un exemple sur une table bidon en SQL normatif :

    la table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    CREATE TABLE MaTable (Clef INT IDENTITY, Profil VARCHAR(1024));
     
    INSERT INTO MaTable VALUES
    ('A'),
    ('A-B'),
    ('A-C-D-A-B'),
    ('B-D'),
    ('D-D-C'),
    ('A-B-A');
    La requête :
    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
    WITH 
    T0 AS
    (SELECT Clef, 1 AS Ligne,
            CASE WHEN POSITION('-', Profil) > 0 THEN LEFT(Profil, POSITION('-', Profil) - 1) ELSE Profil END AS Profil1,
            CASE WHEN POSITION('-', Profil) > 0 THEN RIGHT(Profil, CHARACTER_LENGTH(Profil) - POSITION('-', Profil)) ELSE '' END AS ProfilN
     FROM   MaTable
     UNION ALL
     SELECT Clef, Ligne + 1,
            CASE WHEN POSITION('-', ProfilN) > 0 THEN LEFT(ProfilN, POSITION('-', ProfilN) - 1) ELSE ProfilN END AS Profil1,
            CASE WHEN POSITION('-', ProfilN) > 0 THEN RIGHT(ProfilN, CHARACTER_LENGTH(ProfilN) - POSITION('-', ProfilN)) ELSE '' END AS ProfilN
     FROM   T0
     WHERE  ProfilN <> '' 
    )
    SELECT Clef, Profil1, Ligne 
    FROM T0
    ORDER BY Clef, Ligne
    Le résultat :
    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
    Clef        Profil1   Ligne
    ----------- --------- -----------
    1           A         1
    2           A         1
    2           B         2
    3           A         1
    3           C         2
    3           D         3
    3           A         4
    3           B         5
    4           B         1
    4           D         2
    5           D         1
    5           D         2
    5           C         3
    6           A         1
    6           B         2
    6           A         3
    Il devient alors simplissime de trouver les éléments que vous souhaitez...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    SELECT *
    FROM   CeResultat
    WHERE  Profil1 IN ('A', 'B')
    GROUP  BY Clef
    HAVING COUNT(DISTINCT Profil1) >= 2;
    Merci à l'avenir de respecter la charte de postage !

    Et pour apprendre le langage SQL, rien ne vaut mon site : http://sqlpro.developpez.com/
    Comme mon livre : Nom : Couverture SQL Synthex 4e ed - 500.jpg
Affichages : 39
Taille : 77,8 Ko

    A +

    Ce n'est pas la peine de faire de la publicité gratuite sur votre livre ou sur votre site je n'irai jamais les voir ! Et puis sur la règle de postage j'ai juste oublié la balise CODE, mon message était tout à fait compréhensible la preuve deux personnes censées m'ont répondu.
    Il faut savoir sortir votre tête de vos régles et de vos chartes pour si peu de détail...

    Vous êtes bien gentil comme si j'avais le temps de corriger toutes les failles du modèle que j'utilise, vraiment votre réponse est dénuée de bon sens.

    Bonne journée,

Discussions similaires

  1. [AC-2010] Formulaire - Comment récupérer une partie d'un champ texte
    Par kurtnolan dans le forum IHM
    Réponses: 3
    Dernier message: 10/06/2011, 16h22
  2. Récupérer une partie d'un champ
    Par romeskira dans le forum PHP & MySQL
    Réponses: 7
    Dernier message: 22/09/2008, 21h43
  3. tri sur une partie d'un champ
    Par yoline dans le forum Access
    Réponses: 4
    Dernier message: 19/09/2005, 11h25
  4. Récupérer une partie d'une chaine de caractère
    Par Cyborg289 dans le forum Langage
    Réponses: 5
    Dernier message: 07/07/2005, 14h06
  5. récupérer la partie décimale d’un champ
    Par maouazzani dans le forum MS SQL-Server
    Réponses: 2
    Dernier message: 21/04/2004, 16h10

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