带有负数的sql连接问题

发布于 2024-07-27 21:53:52 字数 619 浏览 5 评论 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 很可能会减慢速度,因此我宁愿将其全部保留在一个命令中。

欢迎您的意见,谢谢:)

I need to select data from two table using a join. This is fairly simple and have no problems here. The problem occurs when the field I am joining is used as two separate foreign keys (I didn't design this). So the ID field that I join on is either a positive or negative number.

If it's a positive number it relates to ID_1 on the table_2 table, if it's a negative, the number relates to ID_2 on the table_2 table. However the ID_2 will be a positive number (even though it's stored as a negative in the foreign key). Obviously there are no constraints to enforce these - so in essence not real foreign keys :/

The SQL I'm using goes something like this and is fine for the positive numbers:

select t1.Stuff, t2.MoreStuff from table_1 t1
join table_2 t2 on t1.ID_1 = t2.ID_1
where ...

How to incorporate the negative aspect of this into the join. Is this even possible? Ideally I'd like to alter the table to my needs but apparently this is not a valid option. I'm well and truly stuck.

The only other idea I've had is a separate sql statement to handle these odd ones. This is all being run by clr sql from C#. Adding a separate SqlCommand to the code will most likely slow things down hence why I'd prefer to keep it all in one command.

Your input is welcome, thanks :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

江心雾 2024-08-03 21:53:52

假设表格如下所示:

Table1 (id INT, foo INT, fk INT)

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

...其中 fk 可用于使用 id1Table2 中查找行(如果为正且 <) code>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)

Let's say the tables look like this:

Table1 (id INT, foo INT, fk INT)

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

...where fk can be used to look up a row in Table2 using id1 if positive and id2 if negative.

Then you can do the join as follows:

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)
冷心人i 2024-08-03 21:53:52

最简单的方法 - 使用 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

Simpliest way - join these tables using 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
困倦 2024-08-03 21:53:52

这不会有很好的性能……但是,什么也不会。 您需要将否定键转换为肯定键,以及连接的条件逻辑。 像这样:

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 函数),但这是在给定情况下您可以做的最好的事情。

This won't be very performant...but then, nothing will. You need to transform your negative key into a positive one, and conditional logic for the join. Like this:

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 ...

No chance of using an index, because you're transforming t1.ID_1 (with the ABS function), but it's the best that you can do given the circumstances.

若沐 2024-08-03 21:53:52

您可以执行类似的操作,但前提是向架构设计者介绍 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,这是最重要的部分!

You can do something like this, but only after introducing the schema designer to a 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

Alternatively,

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

Remember the LART, that's the most important part!

ゃ人海孤独症 2024-08-03 21:53:52

尝试这个

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

try this

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
鹿! 2024-08-03 21:53:52

它必须类似于

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 ...

不确定我是否误解了你的问题。

It will have to be something like

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 ...

Not sure if I have misunderstood your question.

为你拒绝所有暧昧 2024-08-03 21:53:52

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

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_1ID_2不互斥,您将得到 2 个查询结果。

By applying left joins across table two and using the absolute value function, you should be able to accomplish what you're looking for:

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 
   ...

The caveat here is that if ID_1 and ID_2 are not mutually exclusive you will get 2 query results.

怪我闹别瞎闹 2024-08-03 21:53:52
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 ...
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 ...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文