2015-04-22 1 views
0

C'est moi qui assemble des colonnes de 3 tableséléments SQLite en CREATE VIEW duplication

 db.execSQL("CREATE VIEW " + viewComps + 
      " AS SELECT " + COMPANY + "." + colCompID + " AS _id," + 
      " " + ACCOUNTS + "." + colName + "," + 
      " " + COMPANY + "." + colCompClass + "," + 
      " " + PAYMENTS + "." + colGroupID + "," + 
      " " + PAYMENTS + "." + colPayDue + "," + 
      " " + PAYMENTS + "." + colDateDue + "" + 
      " FROM " + PAYMENTS + ", " + COMPANY + 
      " JOIN " + ACCOUNTS + " ON " + PAYMENTS + "." + colGroupID + " = " + ACCOUNTS + "." + colID); 

PROBLÈME

  1. J'ai 3 entreprises A, B et C
  2. Acc 1 est affecté à A, 1 Acc = 1 Société SEULEMENT
  3. Acc 1 est inséré et assigné à A, le problème est même si je l'assigne à A il sera dupliqué pour B et C aussi .

Le résultat:

Acc 1 | Company A | Payment | Date 
    Acc 1 | Company B | Payment | Date 
    Acc 1 | Company C | Payment | Date 

ce qu'il devrait être:

Acc 1 | Company A | Payment | Date 

Chaque autre compte j'insérer dans la base de données fait la même chose et les résultats dans mes entreprises contenant un double de tous les comptes, quelle que soit la société à laquelle le compte est affecté.

QUESTION

Qu'est-ce que je fais mal avec mon point de vue? Je ne comprends pas pourquoi il duplique toutes les entrées en mettant une copie de chaque compte dans chaque entreprise. Quelqu'un peut-il me montrer où est mon erreur? Je suis assez nouveau à ce sujet et pourrait utiliser quelques indicateurs dans ce domaine. Je suis assez confiant que c'est juste un problème avec cette vue car j'ai une autre activité qui affiche des comptes basés sur la compagnie et tout fonctionne bien là-bas au moins.

Je vais laisser les 3 tables les VIEW références en bas au cas où il est nécessaire:

db.execSQL("CREATE TABLE " + COMPANY + " (" + colCompID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      colCompClass + " TEXT)"); 

    db.execSQL("CREATE TABLE " + ACCOUNTS + " (" + colID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      colName + " TEXT, " + 
      colComp + " INTEGER NOT NULL," + 
      colAmount + " INTEGER, " + 
      colPurpose + " TEXT, " + 
      colTerms + " INTEGER NOT NULL, " + 
      colPeriod + " INTEGER NOT NULL, " + 
      colBalance + " INTEGER, "+ 
      colStatus + " INTEGER NOT NULL," + 
      colDate + " TEXT, " + 
      colEditDate + " TEXT, " + 
      colRemarks + " TEXT, " + 
      "FOREIGN KEY (" + colComp + ") REFERENCES " + COMPANY + " (" + colCompID + ")" + "ON DELETE CASCADE," + 
      "FOREIGN KEY (" + colTerms + ") REFERENCES " + TERMS + " (" + colTermsID + ")" + "ON DELETE CASCADE," + 
      "FOREIGN KEY (" + colPeriod + ") REFERENCES " + PERIODS + " (" + colPeriodID + ") " + "ON DELETE CASCADE,"+ 
      "FOREIGN KEY (" + colStatus + ") REFERENCES " + STATUS + " (" + colStatusID + ") ON DELETE CASCADE);"); 

    db.execSQL("CREATE TABLE " + PAYMENTS + " (" + colPayID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      colGroupID + " INTEGER NOT NULL, " + 
      colPayBal + " TEXT, " + 
      colInterest + " TEXT, " + 
      colPayDue + " TEXT, " + 
      colDateDue + " TEXT, " + 
      colPayDate + " TEXT, " + 
      "FOREIGN KEY (" + colGroupID + ") REFERENCES " + ACCOUNTS + " (" + colID + ") ON DELETE CASCADE);"); 

Répondre

1

Lorsque vous effectuez une jointure sans contrainte, il produit un produit cartésien entre les deux ensembles de données - chaque La rangée du côté gauche est combinée avec chaque rangée du côté droit, de sorte que deux tables de taille M et N respectivement jointes produiront un résultat de taille (M x N).

Votre requête d'affichage effectue deux jointures. Une jointure (ACCOUNTS) a une contrainte qui limite la taille de l'ensemble de résultats, mais pas l'autre (COMPANY). Qu'est-ce que cela signifie est lorsque vous rejoignez PAIEMENTS et SOCIETE, vous obtenez une instance de chaque combinaison de paiement et de la société. Il y a 3 En supposant de chacun, il donne ceci:

Company A | Payment 1 
Company A | Payment 2 
Company A | Payment 3 
Company B | Payment 1 
Company B | Payment 2 
Company B | Payment 3 
Company C | Payment 1 
Company C | Payment 2 
Company C | Payment 3 

Votre observation que vous obtenez des comptes dupliqués est, à mon avis, en fait une observation que vous avez des paiements en double. Les comptes sont joints en fonction des paiements, c'est donc cette première jointure qui produit des résultats incorrects.

Ce dont vous avez besoin est une contrainte de jointure pour les deux jointures. En regardant votre schéma, il semble que les paiements et les comptes ont une relation, donc je pense que la requête correcte ressemblerait à ceci:

CREATE VIEW viewComps AS 
SELECT ACCOUNTS.colName, COMPANY.colCompId AS _id, COMPANY.colCompClass, PAYMENTS.colGroupID, PAYMENTS.colPayDue, PAYMENTS.colDateDue 
FROM ACCOUNTS 
JOIN COMPANY ON (COMPANY.colCompId = ACCOUNTS.colComp) 
JOIN PAYMENTS ON (PAYMENTS.colGroupID = ACCOUNTS.colID); 
+0

Merci pour cette explication, c'est très apprécié. À votre santé :) – Cytus