c++ - SQL根据一个表中的行而不是另一个表中的行更新和连接三个表

标签 c++ sql sqlite join

我需要执行一些复杂的 SQL 查询,但我有点卡住了。如果有任何改变,我正在使用 SQLite。

我有以下表结构:

Table G
---------
G_id (primary key) | Other cols ...
====================================
        21
        22
        23
        24
        25
        26
        27 (no g_to_s_map)
        28 

.

Table S
---------
S_id (primary key) |  S_num  | Other cols.....
====================================
        1              1101
        2              1102
        3              1103
        4              1104
        5              1105
        6              1106
        7              1107      (no g_to_s_map, no s_to_t_map)
        8              1108      (no g_to_s_map, there IS an s_to_t_map)
        9              1109      (there is an g_to_s_map, but no s_to_t map)

.

Table T
---------
T_id (primary key) | Other cols...
==================================
        1
        2

然后我还有两个映射表:

Table G_to_S_Map (1:1 mapping, unique values of both g_id and s_id)
----------
G_id (foreign key ref g)| S_id (foreign key ref s)
===================================================
           21                        1  
           22                        2  
           23                        3  
           24                        4  
           25                        5  
           26                        6  
           28                        9

.

Table S_to_T_Map (many:1 mapping, many unique s_id to a t_id)
----------
S_id (foreign key ref s) | T_id (foreign key ref s)
===================================================
           1                         1    
           2                         1    
           3                         1    
           4                         2    
           5                         2    
           6                         2 
           8                         2

只给定一个 T_id 和一个 G_id,我需要能够用第一个 S_idG_to_S_Map strong> 对应于不在 G_to_S_Map

中的指定 T_id(在 S_to_T_Map 中)

我首先想到的是获取与 S_to_T_Map 中的 T_id 相对应的任何 S_id:

SELECT S_id FROM S_to_T_Map where T_id = GIVEN_T_ID;

然后大概我会以某种方式使用 G_to_S_Map 使用左/右连接将这些值连接起来,然后寻找其中一侧不存在的第一个值?然后我需要根据 S_idGIVEN_G_ID 值或其他内容插入到 G_to_S_Map 中。

关于如何解决这个问题有什么建议吗?谢谢!


编辑:添加了一些虚拟数据:

最佳答案

我相信这应该有效:

INSERT INTO G_To_S_Map (G_id, S_id) 
          (SELECT :inputGId, a.S_id
           FROM S_To_T_Map as a
           LEFT JOIN G_To_S_Map as b
           ON b.S_id = a.S_id
           AND b.G_id = :inputGId
           WHERE a.T_id = :inputTId
           AND b.G_id IS NULL
           ORDER BY a.S_id
           LIMIT 1);


编辑:

如果您想通过不同的表进行排序,请使用此版本:

INSERT INTO G_To_S_Map (G_id, S_id) 
          (SELECT :inputGId, a.S_id
           FROM S_To_T_Map as a
           JOIN S as b
           ON b.S_id = a.S_id
           LEFT JOIN G_To_S_Map as c
           ON c.S_id = a.S_id
           AND c.G_id = :inputGId
           WHERE a.T_id = :inputTId
           AND c.G_id IS NULL
           ORDER BY b.S_num
           LIMIT 1);

(顺便说一句,我真的希望您的表实际上不是这样命名的,因为这样做很糟糕。Map 的使用,尤其是,应该可能避免)


编辑:

这是一些示例测试数据。我错过了什么吗?我是否错误地概念化了这些关系?

S_To_T_Map
================
S_ID    T_ID    
   1       1    
   2       1    
   3       1    
   1       2    
   1       3    
   3       3 

G_To_S_Map
==================   
G_ID    S_ID  
   1       1  
   3       1  
   2       1  
   3       2  
   2       3  
   3       3  

生成的连接数据:
(用于生成交叉连接测试数据的 CTE)

Results:
=============================
G_TEST    T_TEST    S_ID 
     1         1       3 
     2         1       2 
     1         3       3 


编辑:

啊,好的,现在我明白了。我的问题是我假设 SG 之间存在某种多对一关系。由于情况并非如此,请使用此修改后的声明:

INSERT INTO G_To_S_Map (G_id, S_id)  
      (SELECT :inputGId, a.S_id 
       FROM S_To_T_Map as a 
       JOIN S as b 
       ON b.S_id = a.S_id 
       LEFT JOIN G_To_S_Map as c 
       ON c.S_id = a.S_id 
       OR c.G_id = :inputGId
       WHERE a.T_id = :inputTId 
       AND c.G_id IS NULL 
       ORDER BY b.S_num 
       LIMIT 1); 

具体来说,检查 G_To_S_Map 是否包含 G_Id 的行需要从使用 AND 切换为 OR - 之前未指定的关键要求G_IdS_IdG_To_S_Map 中都是唯一的
如果提供的 G_Id 之前已被映射,或者如果映射到给定 T_Id 的所有 S_Id 已被映射,则此语句不会插入一行映射。

关于c++ - SQL根据一个表中的行而不是另一个表中的行更新和连接三个表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9637603/

相关文章:

c++ - 关于多线程程序的查询

c++ - typedef 结构和枚举,为什么?

C++ FFmpeg 刷新后如何继续编码?

SQL 原型(prototype)设计 : facing silent truncation of data using varchar(N) -- any better alternatives? (Teradata)

sql - 用于收集和查询每个日期的文本统计信息的工具

c++ - Qt 应用程序和 Google Breakpad

sql - JPA 按所选列获取结果列表顺序

Java JDBC PreparedStatement 外键约束失败

c# - SQLite 加密因平台而异

ios - Swift 中没有像 Sqlite 这样的模块