Comparer les donnée de même valeur et compter le nombre d'enregistrement

Résolu/Fermé
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 - 11 oct. 2019 à 15:30
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 - 14 oct. 2019 à 08:59
Bonjour,

J'ai trois base dont base1 qui contient tous l'ensemble du base2,base3. Mon code permet de comparé l'enregistrement du base1 au base2 et base3 et si un donnée est manquant alors il l'affiche.
Mais ce que j'aimerais faire cette fois c'est que ce code compte le nombre d'enregistrement du base2 existant dans base1 et même chose pour la base3.
Exemple
base2 contient:
1-Roger
2-Jacques
Résultat: il a deux enregistrement dans base2
base1 contient:
1-Roger
Résultat: il a un seul enregistrement dans base1
Conclusion
Il manque un donnée de la base2 dans base1
C'est quelque chose du genre le résultat que je veux obtenir on modifiant mon code:

import sqlite3

def create_table(db_name, values):
    con = sqlite3.connect("./databases/%s.db" % db_name)
    cur = con.cursor()
    cur.execute(
        '''CREATE TABLE fournisseurs(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            nom TEXT
        )'''
    )
    s = ','.join(('(?)',) * len(values))
    cur.execute('INSERT INTO fournisseurs(nom) VALUES %s' % s, values)
    con.commit()
    con.close()


def tables_dif(main_db_name, *db_names):
    con = sqlite3.connect(":memory:")
    con.execute("ATTACH DATABASE './databases/%s.db' AS main_db" % main_db_name)
    cur = con.cursor()
    res = {}
    for db_name in db_names:
        con.execute("ATTACH DATABASE './databases/%s.db' AS db" % db_name)
        sql = '''
        SELECT "fournisseurs", t2.id, t2.nom
        FROM db.fournisseurs as t2
        LEFT JOIN main_db.fournisseurs as t
        USING(nom)
        WHERE t.nom IS NULL
UNION
SELECT "client", t2.id, t2.nom
        FROM db.client as t2
        LEFT JOIN main_db.client as t
        USING(nom)
        WHERE t.nom IS NULL
        '''
        cur.execute(sql)
        res[db_name] = cur.fetchall()
        con.execute("DETACH DATABASE db")
    con.close()
    return res


try:
    create_table('main', ('jojo', 'mimi', 'riri'))
    create_table('base1', ('jojo', 'riri', 'vévé'))
    create_table('base2', ('riri', 'lulu'))
except:
    pass

print(tables_dif('main', 'base1', 'base2'))


Cordialement,

Configuration: Windows / Firefox 69.0

2 réponses

Bonjour.

En effet, on t'as parlé d'UNION dans ton autre sujet, et là cela convient à faire ce que tu veux, sqlite ne gère pas le full outer join, alors une inversion des tables suffit à récupérér ce que l'on souhaite, vu qu'on souhaire récupérer aussi les valeurs nulles, alors on ne met pas de prédicat where.

Dans la fonction tables_dif, le sql deviendra alors.
sql = '''
SELECT t.nom, t2.nom FROM db.fournisseurs as t2
LEFT JOIN main_db.fournisseurs as t
USING(nom)
UNION
SELECT t.nom, t2.nom FROM main_db.fournisseurs as t
LEFT JOIN db.fournisseurs as t2
USING(nom)
'''


Puis on appelle cette fonction et on en exploite le retour de la réquête.

difs = tables_dif('main', 'base1', 'base2')
for db_name, results in difs.items():
    records = {'main':[], db_name:[], 'commons':[]}
    for line in results:
        if line[0] is None:
            records[db_name].append(line[1])
        elif line[1] is None:
            records['main'].append(line[0])
        else:
            records['commons'].append(line[0])
    print('>>>', db_name)
    commons_len = len(records['commons'])
    print('enregistrements main.fournisseurs :', commons_len + len(records['main']))
    print('enregistrements %s.fournisseurs :' % db_name, commons_len + len(records[db_name]))
    print('Dans les deux tables fournisseurs:', ', '.join(records['commons']))
    print('Seulement dans main.fournisseurs :', ', '.join(records['main']))
    print('Seulement dans %s.fournisseurs :' % db_name, ', '.join(records[db_name]))
    print()


Pour bien comprendre, un simple print de la variable difs devrait suffire.

Il serait quand même mieux de faire des unions sur le même type de table, donc plusieurs requêtes sql, autrement ça risque de devenir vite incompréhensible.
1
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 9
Modifié le 14 oct. 2019 à 09:01
Impeccable, c'est bien ce que je cherche merci! vous me sauve la vie vraiment! je suis très content. Je marque ce sujet comme résolu :-)
1
Bonsoir.

Quel est l'objectif à terme ?
As-tu vraiment besoin de récupérer les lignes de table2 n'étant pas dans table1 ?

Quelle est la structure réelle de tes tables ?
J'imagine quand même que dans tes tables la colonne "nom" doit être UNIQUE, sinon il y a des risques de doublonnages.

Personnellement, si j'étais dans ce cas de figure, je ferai simplement un INSERT ... SELECT, et puis c'est tout.

Un truc comme.
sql = '''INSERT INTO main_db.fournisseurs (nom)
SELECT t2.nom FROM db.fournisseurs as t2
LEFT JOIN main_db.fournisseurs as t
USING(nom)
WHERE t.nom IS NULL
'''


Mais faudrait vraiment décrire précisément ce que tu veux faire de A à Z.

Sinon pour compter, bah; c'est simplement faire une requête
COUNT(*)
de ta table2 puis de soustraire le nombre d'éléments retournés dans
res['table2']
, ce n'est pas très compliqué.
0
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 9
12 oct. 2019 à 10:42
Merci de votre réponse, je crois que avec une image ma question sera un peu plus clair, voici le résultat que j'aimerais avoir:
0
yg_be Messages postés 22702 Date d'inscription lundi 9 juin 2008 Statut Contributeur Dernière intervention 19 avril 2024 1 471 > rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021
12 oct. 2019 à 12:04
c'est de moins en moins clair:
1) ton exemple en #2 est faux, regarde le nombre d’enregistrements par table
2) tu as changé d'avis entre hier à 15h30 et ce matin à 10h42, ta demande a changé.
3) tu écris que tu as 3 bases, et ton exemple n'en montre que 2

par ailleurs, tu as une autre demande qui est en cours: https://forums.commentcamarche.net/forum/affich-36250144-comparaison-de-plusieurs-tables-avec-plusieurs-base-de-donnee
je pense qu'il serait préférable que tu termines d'abord de travailler sur celle-là.

ensuite, que tu réfléchisses bien à ce que tu veux obtenir, et que tu réfléchisses aussi à comment l'obtenir, à essayer avant de faire appel à nous.
0
rasielblas Messages postés 140 Date d'inscription jeudi 20 mars 2014 Statut Membre Dernière intervention 12 mai 2021 9
14 oct. 2019 à 08:57
Merci pour votre aide, je n'ai pas changé d'avis à propos de nombre de base, en fait j'ai même plusieurs bases mais c'est juste un exemple, avant de lancé un discussion je créer mon code, je teste, je faire la correction, c'est quand je suis complètement bloqué que je postule un sujet mais merci quand même pour cet avis!
0