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

Décisions SGBD Discussion :

Existe-t-il un SGBD capable de réaliser une division de string par les espaces en une seule requête ?


Sujet :

Décisions SGBD

  1. #1
    Membre du Club
    Inscrit en
    Mars 2009
    Messages
    104
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 104
    Points : 69
    Points
    69
    Par défaut Existe-t-il un SGBD capable de réaliser une division de string par les espaces en une seule requête ?
    Bonjour à tous,

    Je me demande s'il existe des SGBDs qui gèrent des requêtes comme il suit: J'ai une string en entrée. C'est un ensemble de mots séparés par des espaces. La tâche à réaliser consiste à extraire d'un dictionnaire toutes les cellules qui correspondent à un ou plusieurs des mots de la phrase. Par exemple, si je cherche:
    "De toute façon , ça ne marche pas"

    Il me renvoie:
    - De toute façon
    - De
    - toute
    - façon
    -,
    -ça
    -ne
    -marche
    -pas

    Un point à noter: dans ce que je demande, il y a deux types de séparateurs à mobiliser. Le premier, le plus simple, c'est l'espace. Un espace entre deux mots conduit à chercher chacun d'eux. Le second séparateur est plus compliqué. Il existe des groupes de mots contigus dans mon fichier qui contiennent un espace. Je veux aussi pouvoir les identifier.

    J'ai une expérience assez limitée des SGBD (mySQL et SQLite essentiellement) et je voudrais me faire confirmer par des spécialistes si oui ou non c'est possible.

    Par avance, merci

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 739
    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 739
    Points : 52 451
    Points
    52 451
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par billybobbonnet Voir le message
    Je me demande s'il existe des SGBDs qui gèrent des requêtes comme il suit: J'ai une string en entrée. C'est un ensemble de mots séparés par des espaces. La tâche à réaliser consiste à extraire d'un dictionnaire toutes les cellules qui correspondent à un ou plusieurs des mots de la phrase. Par exemple, si je cherche:
    "De toute façon , ça ne marche pas"
    SQL étant un langage complet au sens de Turing, tout problème bien posé peut être résolu en une seule requête.

    1) voici comment poser le problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CREATE TABLE T_LIGNE (PHRASE VARCHAR(256));
     
    INSERT INTO T_LIGNE VALUES ('De toute façon , ça ne marche pas');
    2) voici la requête qui le résout :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    WITH T_MOT AS
    (SELECT SUBSTRING(PHRASE, 1, CHARINDEX(' ' , PHRASE)) AS MOT, 
            SUBSTRING(PHRASE, CHARINDEX(' ' , PHRASE) + 1, LEN(PHRASE) - CHARINDEX(' ' , PHRASE)) AS PHRASE 
     FROM   T_LIGNE
     UNION ALL
     SELECT SUBSTRING(PHRASE, 1, CHARINDEX(' ' , PHRASE)) AS MOT, 
            SUBSTRING(PHRASE, CHARINDEX(' ' , PHRASE) + 1, LEN(PHRASE) - CHARINDEX(' ' , PHRASE)) AS PHRASE 
     FROM   T_MOT
     WHERE  CHARINDEX(' ' , PHRASE) > 0
    )
    SELECT MOT
    FROM T_MOT;
    Et le résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    MOT
    -------------------
    De 
    toute 
    façon 
    , 
    ça 
    ne 
    marche
    Exécuté sur MS SQL Server. Malheureusement ni MySQL ni SQLLite ne peuvent reproduire cette requête. L'un comme l'autre sont trop pauvre et en sont resté au SQL d'il y a plus de 20 ans (SQL 2 de 1992 !!!)
    En revanche vous pouvez faire cela sur Oracle, IBM DB2, SYbase ASA et ASE, SQL Server, PostGreSQL.... bref tout bon SGBDR et non pas un ersatz !

    À lire sur le sujet : http://sqlpro.developpez.com/cours/s...te-recursives/

    A +

    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/ * * * * *

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Une récursive n'est pas indispensable. On peut aussi s'appuyer sur une table de nombre, ce qui sera probablement plus performant :

    ça devrait passer sur n'importe quel SGBD en adaptant les fonctions chaine si besoin :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    SELECT 
    	SUBSTRING(PHRASE, n, CHARINDEX(' ',PHRASE + ' ', n + 1  ) - n ) 
    FROM T_LIGNE
    INNER JOIN Nombre
    	ON	n < LEN(PHRASE)
    	AND (
    		SUBSTRING(PHRASE, n , 1) = ' '
    		OR n = 0
    	)
    ;
    Pour résoudre votre deuxième problème :
    Si j'ai bien compris, vous disposez d'une liste de mots (ou de groupe de mots). d'une sorte de dictionnaire servant de base pour votre recherche ?
    Si c'est bien ça, vous pouvez aussi avantageusement vous en servir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    SELECT Terme
    FROM Dico
    INNER JOIN T_LIGNE
    	ON PHRASE LIKE '%' + Terme + '%'
    ORDER BY CHARINDEX(Terme, PHRASE)
    Ce qui aura l'avantage de faire ressortir le groupe "de toute façon" s'il est présent dans le dictionnaire.
    En revanche, les mots présents plusieurs fois ne ressortiront qu'une fois. (il est également possible de régler ce problème).

    bref, un seul problème mais beaucoup de solutions. A vous de choisir la meilleure en fonction de votre contexte, de vos besoins,...

  4. #4
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 021
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Janvier 2007
    Messages : 15 021
    Points : 40 934
    Points
    40 934
    Billets dans le blog
    62
    Par défaut
    Bonjour,
    Dans les ... de la liste de SQLPro je rajouterais Firebird (et donc in extenso INTERBASE) à moins qu'elles ne soient pas considérées comme "bref tout bon SGBDR"
    car peu citées ?
    MVP Embarcadero
    Delphi installés : D3,D7,D2010,XE4,XE7,D10 (Rio, Sidney), D11 (Alexandria), D12 (Athènes)
    SGBD : Firebird 2.5, 3, SQLite
    générateurs États : FastReport, Rave, QuickReport
    OS : Window Vista, Windows 10, Windows 11, Ubuntu, Androïd

  5. #5
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 : 4 146
    Points : 7 388
    Points
    7 388
    Billets dans le blog
    1
    Par défaut
    Plutôt que de se lancer dans des requêtes imbitables (bah ouais, désolé), je serais tenté de dire que :
    - on cherche à faire un SPLIT
    - qu'un SPLIT (résursif ou non) en SQL ou PL/SQL est une mauvaise idée
    - que dans les langages procéduraux classiques, c'est absolument natif
    - et que ça tombe bien, certains SGBD (SQL Server, Oracle par exemple) peuvent être étendus avec des procédures en langage procédural compilé

    Et par conséquent, je vous renvoie à mon excellent topic (faut bien que je m'envoie des fleurs, à défaut d'en recevoir) :

    http://www.developpez.net/forums/d14...r/#post7927380

    Je doute très fortement que les solutions proposées ci-dessus puissent être plus performantes, ni ne tiennent mieux la charge.
    On ne jouit bien que de ce qu’on partage.

  6. #6
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 739
    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 739
    Points : 52 451
    Points
    52 451
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par StringBuilder Voir le message
    ...je serais tenté de dire que :
    - qu'un SPLIT (résursif ou non) en SQL ou PL/SQL est une mauvaise idée
    Pourquoi ?
    - que dans les langages procéduraux classiques, c'est absolument natif
    ha oui et les renvoyer dans une table ???
    - et que ça tombe bien, certains SGBD (SQL Server, Oracle par exemple) peuvent être étendus avec des procédures en langage procédural compilé

    Et par conséquent, je vous renvoie à mon excellent topic (faut bien que je m'envoie des fleurs, à défaut d'en recevoir) :

    http://www.developpez.net/forums/d14...r/#post7927380

    Je doute très fortement que les solutions proposées ci-dessus puissent être plus performantes, ni ne tiennent mieux la charge.
    Et bien, il faut tester.... Tu sera, sans doute surpris que certaines choses en Transact SQL vont plus vites que certaines autres en .net....

    As tu fait les tests ?

    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/ * * * * *

  7. #7
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 : 4 146
    Points : 7 388
    Points
    7 388
    Billets dans le blog
    1
    Par défaut
    Autant mes tests ne sont pas forcément probants dans le sens où il ne s'agit pas de conditions de benchmarking idéales (je n'ai testé que la méthode CLR, sur un serveur Express, non dédié, avec une volumétrie somme toute assez faible).
    Autant les résultats que j'ai pu constater, dans mon environnement, sont plus qu'encourageants, dans la mesure où là où je m'attendais à plusieurs dizaines de secondes de traitements (ce qui aurait été parfaitement supportable vu le besoin), je me suis retrouvé face à des résultats où je traitais plus de 50000 lignes en moins d'une seconde.
    => Mise à part si une autre solution est parfaitement mauvaise, pas moyen de tirer des conclusions à partir d'un tel résultat... Il faudrait une situation telle que le traitement dure plusieurs dizaines de secondes, afin de comparer.
    On ne jouit bien que de ce qu’on partage.

  8. #8
    Membre expert
    Avatar de alassanediakite
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2006
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : Mali

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2006
    Messages : 1 599
    Points : 3 590
    Points
    3 590
    Billets dans le blog
    8
    Par défaut
    Salut
    Le problème est peut-être plus compliqué que je ne le crois, mais avec PostgreSQL...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select t.mot from unnest(string_to_array('De toute façon , ça ne marche pas',' ')) as t(mot)
    donne le même résultat que pour SQLpro.
    En voulant convertir le code de ai+3e+5u
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT 
    	SUBSTRING(PHRASE from n for position(' ' in substring(PHRASE|| ' ' from n + 1) ) - n ) 
    FROM (select 'De toute façon , ça ne marche pas'::text as PHRASE) as T_LIGNE
    INNER JOIN (select t.n from generate_series(0,8) as t(n)) as Nombre
    	ON	n < length(PHRASE)
    	AND (
    		SUBSTRING(PHRASE from n for 1) = ' '
    		OR n = 0
    	)
    j'obtiens deux ligne "de" et " to"
    @+
    Le monde est trop bien programmé pour être l’œuvre du hasard…
    Mon produit pour la gestion d'école: www.logicoles.com

  9. #9
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 146
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    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 : 4 146
    Points : 7 388
    Points
    7 388
    Billets dans le blog
    1
    Par défaut
    Avec SQL Server et ma fonction Split :
    Code sql : 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
    27
    28
    29
    30
     
    with dico
    as
    (
    	select 'marche' mot
    	union all
    	select 'de toute façon'
    	union all
    	select 'il a raison'
    ),
    dico_tmp as
    (
    	select dico.mot, detail.ligne
    	from dico
    	cross apply dbo.split(dico.mot, ' ') detail
    ),
    dico_tmp2 as
    (
    	select dico.mot, count(detail.ligne) nb
    	from dico
    	cross apply dbo.split(dico.mot, ' ') detail
    	group by dico.mot
    )
    select dico_tmp.mot
    from dico_tmp
    inner join dico_tmp2 on dico_tmp2.mot = dico_tmp.mot
    inner join dbo.split('de toute façon , ça ne marche pas', ' ') split on split.ligne = dico_tmp.ligne
    group by dico_tmp.mot, dico_tmp2.nb
    having count(*) = dico_tmp2.nb
    ;

    mot
    --------------
    de toute façon
    marche

    (2*ligne(s) affectée(s))

    En revanche, petit bémol ceci dit : si le dictionnaire contient "pas toute", le terme sera aussi trouvé, car ma requête ne vérifie pas l'ordre des mots ni leur proximité

    PS : Mais de toute façon, vu comme c'est parti, on cherche plutôt à faire du FULLTEXT qu'autre-chose...

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    CONTAINS(macolonne, ' "de toute façon" AND "marche" ')
    On ne jouit bien que de ce qu’on partage.

  10. #10
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par alassanediakite Voir le message
    En voulant convertir le code de ai+3e+5u
    sous PG, ce serait comme ceci par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    SELECT 
    	SUBSTRING(PHRASE from n + 1 for position(' ' in substring(PHRASE|| ' ' from n + 1))) 
    FROM (select 'De toute façon , ça ne marche pas'::text as PHRASE) as T_LIGNE
    INNER JOIN (select t.n from generate_series(0,50) as t(n)) as Nombre
    	ON	n < char_length(PHRASE)
    	AND (
    		SUBSTRING(PHRASE from n for 1) = ' '
    		OR n = 0
    	)

Discussions similaires

  1. Réponses: 2
    Dernier message: 08/07/2008, 13h09
  2. Réaliser un classement de performances par personne
    Par stephk dans le forum Requêtes
    Réponses: 4
    Dernier message: 19/06/2008, 21h56
  3. Réponses: 4
    Dernier message: 16/01/2007, 16h27
  4. Réponses: 2
    Dernier message: 04/07/2006, 11h26
  5. [SGBD] Renvoyer les enregistrements d'une base de données mysql
    Par pod1978 dans le forum SQL Procédural
    Réponses: 1
    Dernier message: 30/01/2006, 22h01

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