我需要使用连接从两个表中选择数据。这很简单,在这里没有问题。当我加入的字段被用作两个单独的外键时(我没有设计这个),就会出现问题。因此,我加入的ID字段是正数或负数。
如果它是一个正数,它与table_2表上的ID_1相关,如果它是负数,则该数字与table_2表上的ID_2相关。然而,ID_2将是一个正数(即使它在外键中存储为负数)。显然没有限制来强制执行这些 - 所以本质上不是真正的外键:/
我正在使用的SQL就是这样的,对于正数来说很好:
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1
where ...
如何将此消极方面纳入联接。这甚至可能吗?理想情况下,我想根据我的需要改变表格,但显然这不是一个有效的选择。我很好,真的卡住了。
我唯一的另一个想法就是使用单独的sql语句来处理这些奇怪的问题。这一切都是由来自C#的clr sql运行的。在代码中添加单独的SqlCommand很可能会减慢速度,因此我更倾向于将它全部保存在一个命令中。
欢迎您提出意见,谢谢:)
答案 0 :(得分:2)
最简单的方法 - 使用UNION ALL连接这些表:
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1
where t1._ID_1>0
UNION ALL
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on abs(t1.ID_1) = t2.ID_2
where t1._ID_1<0
答案 1 :(得分:2)
假设表格如下:
Table1 (id INT, foo INT, fk INT)
Table2 (id1 INT, id2 INT, bar VARCHAR(100))
... fk
可以Table2
使用id1
查找一行,如果是肯定的话id2
,如果是肯定的话。
然后你可以按如下方式进行连接:
SELECT T1.id, T1.foo, T2.bar
FROM Table1 T1 INNER JOIN Table2 T2
ON (T1.fk > 0 AND T2.id1 = T1.fk)
OR (T1.fk < 0 AND T2.id2 = - T1.fk)
答案 2 :(得分:1)
这不会很有效......但是,什么都不会。您需要将否定键转换为正键,并将条件逻辑转换为连接。像这样:
select t1.Stuff, t2.MoreStuff
from table_1 t1
join table_2 t2 on (t1.ID_1 > 0 AND t1.ID_1 = t2.ID_1)
OR (t1.ID_1 <0 AND ABS(t1.ID_1) = t2.ID_2)
where ...
没有机会使用索引,因为你正在转换t1.ID_1(使用ABS功能),但鉴于这种情况,你可以做到最好。
答案 3 :(得分:1)
您可以执行类似的操作,但只有在将架构设计器引入LART后才能执行此操作:
SELECT
t1.stuff, COALESCE(t2a.morestuff, t2b.morestuff)
FROM
table_1 t1
LEFT JOIN table_2 t2a ON (t1.id_1 > 0 AND t1.id_1 = t2a.id_1)
LEFT JOIN table_2 t2b ON (t1.id_1 < 0 AND t1.id_1 = -1 * t2b.id_2)
// etc
可替换地,
SELECT
t1.stuff, t2.morestuff
FROM
table_1 t1
LEFT JOIN table_2 t2 ON (
(t1.id_1 > 0 AND t1.id_1 = t2.id_1)
OR (t1.id_1 < 0 AND t1.id_1 = -1 * t2.id_2)
)
// etc
记住LART,这是最重要的部分!
答案 4 :(得分:1)
试试这个
DECLARE @Table TABLE(
ID INT,
ForeignKeyID INT
)
INSERT INTO @Table (ID,ForeignKeyID) SELECT 1, 1
INSERT INTO @Table (ID,ForeignKeyID) SELECT 2, 2
INSERT INTO @Table (ID,ForeignKeyID) SELECT 3, -1
INSERT INTO @Table (ID,ForeignKeyID) SELECT 4, -2
DECLARE @ForeignTable TABLE(
ID_1 INT,
ID_2 INT,
Val VARCHAR(MAX)
)
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 1, 11, '1'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 2, 22, '2'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 3, 1, '3'
INSERT INTO @ForeignTable (ID_1,ID_2,Val) SELECT 3, 2, '4'
SELECT *
FROM @Table t INNER JOIN
@ForeignTable ft ON ABS(t.ForeignKeyID) =
CASE
WHEN t.ForeignKeyID > 0
THEN ft.ID_1
ELSE
ft.ID_2
END
答案 5 :(得分:0)
必须是
之类的东西select t1.Stuff, t2.MoreStuff from table_1 t1, table_2 t2 where (t1.ID_1 = t2.ID_1 OR t1.ID_1 = CONCAT("-",t2.ID_1)) where ...
不确定我是否误解了你的问题。
答案 6 :(得分:0)
通过在表2中应用左连接并使用绝对值函数,您应该能够完成您正在寻找的内容:
SELECT t1.Stuff, isnull(t2.MoreStuff, t2_2.MoreStuff)
FROM table_1 t1
LEFT JOIN table_2 t2 ON t1.ID_1 = t2.ID_1
AND t1.ID_1 > 0
LEFT JOIN table_2 t2_2 ON abs(t1.ID_2) = t2_2.ID_2
AND t1.ID_2 < 0
WHERE
...
这里需要注意的是,如果ID_1
和ID_2
不相互排斥,您将获得2个查询结果。
答案 7 :(得分:0)
select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1 or -t1.ID_1 = t2.ID_2
where ...