gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 04:29:08 26 4
gpt4 key购买 nike

我需要执行一些复杂的 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_id G_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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com