0

我需要使用连接从两个表中选择数据。这相当简单,在这里没有问题。当我加入的字段被用作两个单独的外键(我没有设计这个)时,就会出现问题。所以我加入的 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 很可能会减慢速度,因此我更愿意将它全部保存在一个命令中。

欢迎您的意见,谢谢:)

4

8 回答 8

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
于 2009-07-20T14:12:39.970 回答
2

假设表格如下所示:

Table1 (id INT, foo INT, fk INT)

Table2 (id1 INT, id2 INT, bar VARCHAR(100))

... wherefk可用于在Table2使用id1if positive 和ifnegative 时查找一行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)
于 2009-07-20T14:14:43.773 回答
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 函数),但在这种情况下,这是您能做的最好的事情。

于 2009-07-20T14:14:23.150 回答
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,这是最重要的部分!

于 2009-07-20T14:14:33.320 回答
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
于 2009-07-20T14:17:14.300 回答
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 ...

不知道我是否误解了你的问题。

于 2009-07-20T14:11:39.923 回答
0

通过在表二中应用左连接并使用绝对值函数,您应该能够完成您正在寻找的内容:

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 个查询结果。

于 2009-07-20T14:12:01.140 回答
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 ...
于 2009-07-20T14:16:12.677 回答