Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/137.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SQL根据一个表中的行而不是另一个表中的行更新并联接三个表_C++_Sql_Sqlite_Join - Fatal编程技术网

C++ SQL根据一个表中的行而不是另一个表中的行更新并联接三个表

C++ SQL根据一个表中的行而不是另一个表中的行更新并联接三个表,c++,sql,sqlite,join,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

我需要做一个有点复杂的sql查询,我有点卡住了。如果这改变了什么,我将使用SQLite

我有以下表格结构:

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

然后我还有两个映射表:

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

仅给定T\u idG\u id,我需要能够使用第一个S\u id来更新G\u-to\u-S\u映射,第一个S\u id对应于指定的T\u-id(在S\u-to\u-T\u映射中)

我想到的第一件事就是得到任何与S\u-to\u地图中的T\u-id相对应的S\u-id

SELECT S_id FROM S_to_T_Map where T_id = GIVEN_T_ID;
然后我大概会用G_-to_-S_映射将这些值连接起来,可能使用左/右连接,然后查找第一个不存在于其中一侧的值?然后,我需要根据S\u id给定的\u id值或其他内容,插入到G\u-to\u-S\u映射中

有什么关于如何进行的建议吗?谢谢



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

嗯,下面的操作似乎很好,尽管我还没有将“插入”与之结合起来

Select s.S_ID from S as s 
inner join(
    Select st.S_ID from s_to_t_map as st 
    where st.T_ID=???? AND not exists
                    (Select * from g_to_s_Map as gs where gs.S_ID = st.S_ID)
 ) rslt on s.S_ID=rslt.S_ID  ORDER BY s.s_Num ASC limit 1;

我认为这应该是可行的:

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)


编辑:

啊,好吧,现在我明白问题了。我的问题是,我假设
S
G
之间存在某种多个关系。由于情况并非如此,请使用本修订声明:

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\u Id
的行,行检查
G\u-S\u映射
需要从使用
切换到
——之前未指定的关键要求是
G\u-Id
S\u-Id
G\u-S\u映射中都是唯一的


如果提供的
G_Id
之前已映射,或者映射到给定
T_Id
的所有
S_Id
S已映射,则此语句不会插入一行。

如果没有
ORDER BY
,您将得到一个“随机”行。并停止使用“更新”,这在SQL中有非常特殊的含义。标记到表
S
是没有意义的,因为我假设您有必要的fk引用。是的,我的语法中有一个ORDER BY,只是出于此目的而将其删除。是的,我的意思是“插入”而不是“更新”,忘记了条目还不存在。很有趣。谢谢为什么在S_to_T_映射的选择中有一个:inputGId?我想你的比我的多个选择更有效。但是,如果我想按表“s”中名为“s_Num”的字段排序,该怎么办?我使用
作为主机变量(我不知道您的语法是什么样的)。我在
SELECT
部分中使用它的原因是我希望
G_To_S_Map
的结果引用为空-不会有来自表的引用要使用。答案经过编辑,包括对表
S
Ah的参考,谢谢!是的,这些只是经过净化的变量名,否则我会疯狂地使用它们:我只是想知道,这句话是什么:“ON s.id=a.s_id”?不知道s.id应该是什么。也许是b.s_id。还有,“cb.G_id=:inputGId”是指“c.G_id”吗?这些变量名很残酷,我的错;)不幸的是,它似乎不起作用。当我使用上面的更改运行“g_到s_映射”时,我得到了一个已经在其中的值。它只是给我一个s_num最小的值,不管它是否在表中。
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);
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  
Results:
=============================
G_TEST    T_TEST    S_ID 
     1         1       3 
     2         1       2 
     1         3       3 
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);