【发布时间】:2012-04-13 07:28:49
【问题描述】:
我有一个我正在尝试编写的 SQL 查询,但我不太确定如何让它工作。
我有三个表:“s”、“t”和“st”(这是“s”和“t”之间的映射。
table s
=======
primary key sID | val
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
a 0
b 1
c 5
d 6
e 7
table t
=======
primary key tID | val
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
nul -1
bbb 2
ccc 3
ddd 4
table st
========
foreign key sID | foreign key tID
(unique) | (multiple sID to one tID, meaning tID is not unique)
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
a ddd
b ccc
c nul
d ccc
e bbb
所以,所有的 's' 都必须映射到一个 't',但那些不在真正的 't' 上的会被映射到默认/空的 't' (nul)。
val 在 's' 和 't' 中都是唯一的,这意味着如果 table 's' 有 1,则 table 't' 不能有 1。
所以我的问题如下:
给定一组 val(可以是“s”或“t”),我需要在相应 ID 的“st”表中获取 sID 和 tID。问题是如果一个 's' 在集合中但它的 't' 不在集合中,我需要获取值 (sID, 'nul') 而不是 (sID, tID)。
例如,给定值 (3, 1, 6),它将返回对:(b,ccc); (d,ccc);
给定值 (0,4),它将返回对:(a,ddd)
但是,给定值 (6),它需要返回 (d, nul),因为 val 3(对应于 d 映射到的 ccc)不在放。我不需要 null 's',只需要 null 't'。
我正在考虑使用以下语句,但如果只有 's' 在集合中而不是 't' 中,这并不能帮助我返回 "id, nul"。
SELECT st.sID, st.tID FROM t, st WHERE t.tID=st.tID AND (t.val=%_VAL1_% OR t.val=%_VAL_2 OR ......);
这给了我在集合中同时具有“t”和“s”的任何东西(实际上它给了我与集合中的任何“t”相关联的所有“s”),但它没有给出我是他们自己的's'。
也许我可以对“s”中但不在“st”中的任何内容进行后处理,但如果可能的话,我想避免这种情况。
有人有什么建议吗?我有点卡住了。
谢谢!
(注意:s、t 和 st 不是我的真实表名,别担心。此外,不幸的是,主键实际上是文本 GUID,但我试图使其更易于区分)
【问题讨论】:
-
如果我没有弄错的话,从您的模型和数据中我可以看到您有 3 个表来建模一对多关系。为什么不只使用 2 个?你说
all 's' have to be mapped to a 't',那为什么不在's'中的't'加上FK呢? -
它主要是出于可扩展性的目的,并让界面与我开始使用 sqlite 之前的界面有些相似。
-
这个数据库模型看起来很奇怪。您能否分享更多有关它的动机 - 也许不同的模型会更好地为您服务?另外,
st中存在的行{c, null}与根本不存在的行之间有什么区别? -
如果 3,1,6 的值会返回 b,ccc 和 d,ccc,为什么 6 的值会返回 d,null? 6对应d,映射到ccc。还是我误读了什么?
-
@BrankoDimitrijevic:该模型在某种程度上来自尝试与使用 c++ std::maps 而不是关系数据库的预先存在的设置集成,尽管我同意它可能不是最佳选择。同样,返回 c, null 的需要来自 c++ 中我正在尝试做的事情的需要(特别是,基于 val 将数据库的子集合并到另一个数据库中)。