CREATE VIEW 复制中的 SQLite 元素
SQLite elements in CREATE VIEW duplicating
这是我的视图,它将 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 );
问题
- 我有3家公司A、B、C
- Acc 1 分配给 A,1 Acc = 1 Company ONLY
- Acc 1 被插入并分配给 A,问题是即使我将它分配给 A,它也会被复制到 B 和 C。
结果:
Acc 1 | Company A | Payment | Date
Acc 1 | Company B | Payment | Date
Acc 1 | Company C | Payment | Date
应该是什么:
Acc 1 | Company A | Payment | Date
我插入数据库的每个其他帐户都执行相同操作,导致我的公司包含所有帐户的副本,无论该帐户分配给哪个公司。
问题
我的 VIEW 做错了什么?我不明白为什么它会复制所有条目,在每个公司中放置每个帐户的副本。有人可以告诉我我的错误在哪里吗?我对此很陌生,可以在这方面使用一些指示。我相当有信心这只是这个视图的问题,因为我有另一个 activity 显示基于公司的帐户,并且至少在那里一切正常。
我会把 VIEW 引用的 3 个表留在下面,以备不时之需:
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);");
当您执行无约束连接时,它会在两个数据集之间生成笛卡尔积 -- 左侧的每一行都与右侧的每一行相结合,因此两个大小为 M 和 N 的表加入后分别会产生大小为 (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);
这是我的视图,它将 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 );
问题
- 我有3家公司A、B、C
- Acc 1 分配给 A,1 Acc = 1 Company ONLY
- Acc 1 被插入并分配给 A,问题是即使我将它分配给 A,它也会被复制到 B 和 C。
结果:
Acc 1 | Company A | Payment | Date
Acc 1 | Company B | Payment | Date
Acc 1 | Company C | Payment | Date
应该是什么:
Acc 1 | Company A | Payment | Date
我插入数据库的每个其他帐户都执行相同操作,导致我的公司包含所有帐户的副本,无论该帐户分配给哪个公司。
问题
我的 VIEW 做错了什么?我不明白为什么它会复制所有条目,在每个公司中放置每个帐户的副本。有人可以告诉我我的错误在哪里吗?我对此很陌生,可以在这方面使用一些指示。我相当有信心这只是这个视图的问题,因为我有另一个 activity 显示基于公司的帐户,并且至少在那里一切正常。
我会把 VIEW 引用的 3 个表留在下面,以备不时之需:
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);");
当您执行无约束连接时,它会在两个数据集之间生成笛卡尔积 -- 左侧的每一行都与右侧的每一行相结合,因此两个大小为 M 和 N 的表加入后分别会产生大小为 (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);