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

SQLite Discussion :

Un cas d'inner join incohérent


Sujet :

SQLite

  1. #1
    Membre habitué Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 493
    Points : 152
    Points
    152
    Par défaut Un cas d'inner join incohérent
    Bonjour
    soit 2 table

    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
    CREATE TABLE TRB_GT_0120 (
                Code_GT nvarchar(10),
                Libelle nvarchar(50),
                Date_debut   nvarchar(10),
                Date_fin nvarchar(10),
                Description nvarchar(250),
                Ordre_liquidation INTEGER,
                nb_de_nc INTEGER,
                CONSTRAINT TRB_GT_0120_PK PRIMARY KEY (Code_Produit )
                 );
     
     
     
     
    CREATE TABLE vsl_GTs(
                GT_CODE TEXT(10) NOT NULL,
                GT_DATE_DEBUT TEXT(10),
                GT_DATE_FIN TEXT(10),
                GT_DESCRIPTION TEXT(75),
                GT_LIBELLE TEXT(75),
                CONSTRAINT GTs_PK PRIMARY KEY(GT_CODE)
            );

    Hormis le fait sqllite pourrais avoir quelque soucis avec le type de donnée nvarchar est qu'il serait peut être plus pertinent d'utiliser pour la création de la table des type TEXT.

    voici ce que donne la comparaison des 2 tables
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    select count(*) from vsl_GTs a ;
    retourne :29937

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select count(*) from TRB_GT_0120 b ;
    retourne :36063


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    select  count(*) from vsl_GTs a inner join TRB_GT_0120 b
    on a.GT_CODE = b.Code_GT;
    retourne :36062

    J'ai quelque interrogation sur le fait suivant avec seulement 29937 enregistrements dans la table vsl_GTs
    comment une inner join peu elle retourné plus de donnée que d'enregistrement en table vsl_GTs


    autre point

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select  count(*) from vsl_GTs a where a.GT_CODE in ( select b.Code_GT from  TRB_GT_0120 b);
    renvoie quelque chose de plus cohérent

    29500 enregistrement

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dedalios Voir le message
    J'ai quelque interrogation sur le fait suivant avec seulement 29937 enregistrements dans la table vsl_GTs
    comment une inner join peu elle retourné plus de donnée que d'enregistrement en table vsl_GTs
    Bonjour
    Ca peut arriver si les index de jointure ne sont pas uniques. Dans ce cas, la jointure (qui relie chaque élément de T1 avec chaque élément de T2) donnera card(éléments de T1 qui matchent la requête) x card(éléments de T2 qui matchent la requête) résultats. C'est d'ailleurs pas pour rien si le symbole "jointure" ressemble au symbole "multiplication" quand on modélise une requête SQL dans Merise...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  3. #3
    Membre habitué Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 493
    Points : 152
    Points
    152
    Par défaut
    Comment dans le cas qui nous occupe pourrait on avoir des index non uniques sur des clés primaires ?

  4. #4
    Membre habitué Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 493
    Points : 152
    Points
    152
    Par défaut inserton et sqllite
    Soit la table suivant
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    CREATE TABLE vsl_modules(
                MOD_CODE TEXT(10) NOT NULL,
                MOD_LIBELLE TEXT(255),
                CONSTRAINT modules_PK PRIMARY KEY(MOD_CODE)
            );
    on insert des données dans table via des insert.

    puisje lance
    select max(LENGTH(MOD_CODE)) from vsl_modules
    Quelle est la valeur que j'obtiens: 28

    Comme si la limite de longueur du champ n'était pris en compte.?

    curieux?

  5. #5
    Rédacteur/Modérateur

    Avatar de SergioMaster
    Homme Profil pro
    Développeur informatique retraité
    Inscrit en
    Janvier 2007
    Messages
    15 036
    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 036
    Points : 40 941
    Points
    40 941
    Billets dans le blog
    62
    Par défaut
    Bonjour,

    Curieux, oui. Du coup en lisant vos quelques constatations (ce post et d'autres) j'ai voulu voir ce qu'il en était dans la doc officielle de SQLite et même fouiller un peu dans les peu nombreuses tables système.
    Déjà les FAQ me laissent perplexe
    la réponse à la question 9 (Q9) à propos des varchar indiquant (en gros) qu'il est inutile de faire un effort de restriction de taille
    les indications sur le dynamic typing qui font que la saisie d'un texte soit accepté dans une colonne numérique (Q3)

    J'ai même lu (je ne retrouve plus la page) que pour des raisons de compatibilité descendante, les contraintes référentielles n'était pas très strictes sauf à indiquer un #PRAGMA foreign_keys

    En bref, de quoi prendre SQLite avec des pincettes quand on a l'habitude de SGBDR très normalisé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

  6. #6
    Membre habitué Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 493
    Points : 152
    Points
    152
    Par défaut A prendre avec des pincettes
    Bonjour,
    Effectivement a prendre avec des pincettes


    voici un extrait de code python en lien avec la discutution
    https://www.developpez.net/forums/d1...-postgre-10-a/


    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
     
    # coding: utf-8  
    import sqlite3
    cx = sqlite3.connect(':memory:')
    cx.execute('create table t3(a text(10) primary key, b text);')
     
     
    cx.executemany('insert into t3 values(?, ?)',
                 [('G0000000000', 'a'), ('G0000000000ZZZ', 'b'), ('G0000000000QQQ', 'b')])
     
     
    cx.commit()
     
    row = cx.execute( ('select  lENGTH(a) from t3 ;'   ))
     
    valeur  = row.fetchall()
    print(valeur)
     
     
    row = cx.execute( ('select max( lENGTH(a)) from t3 ;'   ))
     
    valeur  = row.fetchall()
    print(valeur)
    les print retourne ceci

    ----------------------------------
    [(11,), (14,), (14,)]
    [(14,)]



    et effectivement


    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
    cx = sqlite3.connect(':memory:')
    cx.execute('create table t3(a text(10) primary key, b text n , PRAGMA foreign_keys);')
    
    
    cx.executemany('insert into t3 values(?, ?)',
                 [('G0000000000', 'a'), ('G0000000000ZZZ', 'b'), ('G0000000000QQQ', 'b')])
    
    
    cx.commit()
    
    row = cx.execute( ('select  lENGTH(a) from t3 ;'   ))
                        
    valeur  = row.fetchall()
    print(valeur)
    
    
    row = cx.execute( ('select max( lENGTH(a)) from t3 ;'   ))
                        
    valeur  = row.fetchall()
    print(valeur)

    ----------------------------------
    Traceback (most recent call last):
    File "C:\Users\serveeric37\eclipse-workspace\vslrecette\src\x.py", line 59, in <module>
    [('G0000000000', 'a'), ('G0000000000ZZZ', 'b'), ('G0000000000QQQ', 'b')])
    sqlite3.OperationalError: table t4 has 3 columns but 2 values were supplied

  7. #7
    Membre éprouvé
    Homme Profil pro
    Chef de projets retraité
    Inscrit en
    Juillet 2011
    Messages
    420
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Chef de projets retraité
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2011
    Messages : 420
    Points : 1 102
    Points
    1 102
    Par défaut
    Bonjour

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cx.execute('create table t3(a text(10) primary key, b text n , PRAGMA foreign_keys);')
    Comme ceci tu crées un table avec 3 colonnes la troisième se nomme PRAGMA

    Donc ton message est bon tu essaies d'insérer deux valeurs dans une table à trois colonnes sans en donner la liste.

    Pour faire ce que tu demandes (renforcer les clés étrangères) il te faut deux instructions:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    PRAGMA foreign_keys = 1;
    create table t3(a text(10) primary key, b text n );
    Mais comme l'a dit SergioMaster il n'est pas possible de limite la taille d'un champ en SQLITE. Pire il n'est même pas possible d'en contraindre le type. Tu peux définir une colonne en numérique et lui assigner du texte SQLITE ne te dira rien! à l'inverse non plus.

    et pour info le résultat de tes requêtes est 14

    Cordialement

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 685
    Points : 30 974
    Points
    30 974
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par dedalios Voir le message
    Comment dans le cas qui nous occupe pourrait on avoir des index non uniques sur des clés primeres ?
    Là je ne vois pas trop. Mais au lieu de faire du count(*), pourquoi tu n'afficherais pas directement le résultat du select ? Avec un petit "order by" bien ajusté et tu verrais alors les doublons (parce que fatalement il doit y en avoir ; soit dans la partie gauche, soit dans la droite de la jointure) et peut-être que tu arriverais à en déterminer la cause...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre habitué Avatar de dedalios
    Homme Profil pro
    concepteur d'application
    Inscrit en
    Février 2008
    Messages
    493
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Indre et Loire (Centre)

    Informations professionnelles :
    Activité : concepteur d'application
    Secteur : Santé

    Informations forums :
    Inscription : Février 2008
    Messages : 493
    Points : 152
    Points
    152
    Par défaut La vérité est ailleurs
    merci a tous :

    il y avait une erreur de saisie dans la table TRB_GT_0120, sur la clé primaire définie dans l'exemple

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE TRB_GT_0120 (
                Code_GT nvarchar(10),
                Libelle nvarchar(50),
                Date_debut   nvarchar(10),
                Date_fin nvarchar(10),
                Description nvarchar(250),
                Ordre_liquidation INTEGER,
                nb_de_nc INTEGER,
                CONSTRAINT TRB_GT_0120_PK PRIMARY KEY (Code_Produit )
                 );
    Code_Produit n'est pas la clé primaire du fichier

    Le description de la table serait plutot

    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
    CREATE TABLE TRB_GT_0120 (
                Code_GT nvarchar(10),
                Libelle nvarchar(50),
                Date_debut   nvarchar(10),
                Date_fin nvarchar(10),
                Description nvarchar(250),
                Ordre_liquidation INTEGER,
                nb_de_nc INTEGER,
                CONSTRAINT TRB_GT_0120_PK PRIMARY KEY (Code_GT )
                 );
     
     
    CREATE TABLE TRB_GT_0120 (
                Code_GT nvarchar(10) PRIMARY KEY,
                Libelle nvarchar(50),
                Date_debut   nvarchar(10),
                Date_fin nvarchar(10),
                Description nvarchar(250),
                Ordre_liquidation INTEGER,
                nb_de_nc INTEGER 
                 );
    Les 2 syntaxes sont utilisables mais sont-elles identiques
    D'où ma perplexité de comparaison pour ces 2 tables :

    Puis après avoir vérifié une troisième fois


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE TRB_GT_0120 (
                Code_GT nvarchar(10),
                Libelle nvarchar(50),
                Date_debut   nvarchar(10),
                Date_fin nvarchar(10),
                Description nvarchar(250),
                Ordre_liquidation INTEGER,
                nb_de_nc INTEGER,
                CONSTRAINT TRB_GT_0120_PK PRIMARY KEY (Code_GT,Date_debut )
                 );
    La clé primaire est plus complexe donc le résultat de la jointure comme tout le monde l’explique était des plus logiques.


    A trop regarder de près on ne voit plus quelque fois les évidences, il est allons une bonne chose de reposer nos yeux de ses écran et de profiter du beau temps.

Discussions similaires

  1. Mysql Inner join
    Par ..:: Atchoum ::.. dans le forum Requêtes
    Réponses: 3
    Dernier message: 25/10/2007, 12h21
  2. Nombre de clauses ON dans un INNER JOIN
    Par Shadow aok dans le forum Requêtes
    Réponses: 5
    Dernier message: 30/06/2004, 15h42
  3. [ requeste sql ]INNER JOIN / OUTER JOIN
    Par hocinema dans le forum Langage SQL
    Réponses: 2
    Dernier message: 12/04/2004, 21h28
  4. Erreur lors d'une requete INNER JOIN
    Par k-lendos dans le forum Langage SQL
    Réponses: 2
    Dernier message: 17/03/2004, 15h09
  5. Inner Join & Select
    Par bakaneko dans le forum Langage SQL
    Réponses: 7
    Dernier message: 10/02/2004, 10h48

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