通过SQL

时间:2016-08-11 07:58:38

标签: mysql sql

我有以下一组表用于管理基于纸质文档的程序:

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应用程序的后端。

1 个答案:

答案 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;