我有以下一组表用于管理基于纸质文档的程序:
CREATE TABLE TableA (
`id` int NOT NULL AUTO_INCREMENT,
`data` varchar(256),
`type` varchar(3)
);
TableA
保存相关的过程数据(用于业务逻辑)。 type
字段标识了'过程的类型'我在管理。
CREATE TABLE Templates (
`id` int NOT NULL AUTO_INCREMENT,
`type` varchar(3),
`id_doc_type` int NOT NULL,
);
Templates
列出了填写特定类型的程序所需的所有文档类型。
CREATE TABLE CheckList (
`id` int NOT NULL AUTO_INCREMENT,
`id_doc_type` int NOT NULL,
`id_tableA` int NOT NULL,
`filled` tinyint(1) DEFAULT '0'
);
CheckList
应包含一组记录,其中包含要为TableA
的每个记录接收的文档类型,用户使用filled
字段来确认指定文档类型的接收
CREATE TABLE DocTypes (
`id` int NOT NULL AUTO_INCREMENT,
`doc_type` varchar(24)
);
DocTypes
详细描述了文档的类型。
希望表和字段名称有助于找到它们的范围。
此类表格的典型内容如下:
TableA:
------------------------------
id | data | type
------------------------------
0 | data0 | M
1 | data1 | M
2 | data2 | S
3 | data3 | M
4 | data4 | S
------------------------------
Templates:
------------------------------
id | type | id_doc_type
------------------------------
0 | M | 0
1 | M | 1
2 | M | 2
3 | S | 0
4 | S | 1
------------------------------
CheckList:
----------------------------------------
id |id_doc_type| id_tableA | filled
----------------------------------------
0 | 0 | 0 | 1
1 | 1 | 0 | 1
2 | 2 | 0 | 1
3 | 0 | 2 | 0
4 | 1 | 2 | 0
5 | 0 | 1 | 0
6 | 1 | 1 | 1
----------------------------------------
DocTypes:
------------------------------
id | doc_type
------------------------------
0 | doc_type 0
1 | doc_type 1
2 | doc_type 2
------------------------------
我编写了几个存储过程来管理这些表,但由于某种原因,由于以前的数据管理模型,CheckList
表有一些“漏洞”。就像上面描述的那样:
正如您所看到的,只有id
的记录0,1(指TableA
值)具有CheckList
中的完整文档类型引用集,记录2只有部分集合文档类型引用和记录3,4完全缺失。
我需要编写一个SQL过程来填充保存现有数据的所有内容,并避免创建欺骗。
正如我所说,我已经写了程序。其中我写了一个填充空CheckList
部分(即它为TableA
完全未引用的记录创建记录集,就像记录3和4)但我无法弄清楚如何部分恢复记录2等情况。
正如评论中所建议的,这是CheckList
表在完成程序后应该是什么样子:
CheckList:
-----------------------------------------
id |id_doc_type| id_tableA | filled
-----------------------------------------
0 | 0 | 0 | 1
1 | 1 | 0 | 1
2 | 2 | 0 | 1
3 | 0 | 2 | 0
4 | 1 | 2 | 0
5 | 0 | 1 | 0
6 | 1 | 1 | 1
7 | 2 | 1 | 0
8 | 0 | 3 | 0
9 | 1 | 3 | 0
10 | 2 | 3 | 0
11 | 0 | 4 | 0
12 | 1 | 4 | 0
-----------------------------------------
我编写的填充存储过程的一部分经过修改以符合我的需要(但不能正常工作):
INSERT INTO CheckList (id_doc_type, id_tableA)
SELECT id_doc_type, @id_tableA
FROM Templates
WHERE
type = @type
AND NOT (id_doc_type IN (
SELECT id_doc_type
FROM CheckList
WHERE
id_tableA = @id_tableA));
当然@id_tableA
和@type
是我的过程的参数,而在这种情况下它们不能被使用(或者它们可以但我们需要一个迭代tableA
记录的外部过程)。
我使用MySQL 5.7作为ASP.NET Web应用程序的后端。
答案 0 :(得分:0)
考虑一下
insert into checklist (id_doc_type, id_tablea, filled)
select t.id_doc_type as id_doc_type, a.id as id_tablea, 0 as filled
from tablea a
join templates t on a.type = t.type
left join checklist c on a.id = c.id_tablea and t.id_doc_type = c.id_doc_type
where c.id is null;