CREATE VIEW中的SQLite元素重复

时间:2015-04-22 15:49:41

标签: android sqlite sql-view

这是我的观点,它将3个表中的列放在一起

        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 );

问题

  1. 我有3家公司A,B和C
  2. Acc 1分配给A,1 Acc = 1 Company ONLY
  3. 插入Acc 1并分配给A,问题是即使我将其分配给A,它也会被复制为B和C.
  4. 结果:

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

    应该是什么:

      Acc 1 | Company A | Payment | Date
    

    我插入到数据库中的每个其他帐户都会执行相同操作,并导致我的公司包含所有帐户的副本,而不管该帐户分配给哪个公司。

    问题

    我的视图有什么问题?我不明白为什么它会复制所有条目,将每个帐户的副本放在每个公司中。有人能告诉我我的错误在哪里吗?我对此很新,可以在这方面使用一些指针。我非常有信心这只是这个观点的一个问题,因为我有另一个基于公司显示帐户的活动,它至少在那里工作得很好。

    如果需要,我会在下面的3个表中保留VIEW参考:

        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);");
    

1 个答案:

答案 0 :(得分:1)

当您执行没有约束的连接时,它会在两个数据集之间生成笛卡尔积 - 左侧的每一行与右侧的每一行组合,因此两个表的大小分别为M和N join将产生大小(M x N)的结果。

您的视图查询执行两个连接。一个连接(ACCOUNTS)具有限制结果集大小的约束,但另一个(COMPANY)没有。这意味着当您加入PAYMENTS和COMPANY时,您将获得支付和公司的每种组合的实例。假设每个中有3个,它产生了这个:

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

在我看来,您认为自己获得重复帐户的观察实际上是您有重复付款的观察结果。这些帐户是根据付款加入的,因此这是第一次产生错误结果的加入。

您需要的是两个连接的连接约束。看看你的架构,看起来付款和帐户有关系,所以我认为正确的查询看起来像这样:

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);