Sql 有没有一种方法可以让这个查询处理连接,或者我必须使用联合?
我可能正在尝试将联接用于此处不打算使用的目的 以下是我的(简化)表格结构: 表ASql 有没有一种方法可以让这个查询处理连接,或者我必须使用联合?,sql,sql-server,Sql,Sql Server,我可能正在尝试将联接用于此处不打算使用的目的 以下是我的(简化)表格结构: 表A 身份证 表C ID IsStatic(位) 表B 身份证 表A ID(可为空) 表C ID 表C 身份证 我的目标是将表B的所有行连接到表A的行,其中表B的表A ID列有一个值,并且等于表A的ID列值 我还需要表B的表A ID列没有值的所有表B行 我还需要表A的所有行,其中没有连接的表B行,并且表A的IsStatic列为true 表C还必须与表A或表B关联。如果表B没有TableAID的值,则Table
- 身份证
- 表C ID
- IsStatic(位)
- 身份证
- 表A ID(可为空)
- 表C ID
- 身份证
DECLARE @TableA TABLE (TableAID int, TableCID int, IsStatic bit)
DECLARE @TableB TABLE (TableBID int, TableAID int, TableCID int)
DECLARE @TableC TABLE (TableCID int)
INSERT INTO @TableC (TableCID) VALUES (1)
INSERT INTO @TableC (TableCID) VALUES (2)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (1, 1, 0)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (2, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (3, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (4, 2, 0)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (1, NULL, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (2, 1, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (3, 2, 2)
select a.TableAID, b.TableBID
from @TableA a
full outer join @TableB b
on b.TableAID = a.TableAID
where b.TableBID is not null or a.IsStatic = 1
以下是我的(简化的)查询,它不太有效:
SELECT
a.TableAID,
b.TableBID
FROM @TableC c
LEFT OUTER JOIN @TableB b ON
(b.TableAID IS NOT NULL OR (b.TableAID IS NULL AND b.TableCID = c.TableCID))
LEFT OUTER JOIN @TableA a ON
a.TableCID = c.TableCID
AND ((a.IsStatic = 1 AND b.TableBID IS NULL)
OR (b.TableBID IS NOT NULL AND b.TableAID = a.TableAID))
使用sampel数据的查询结果为:
TableAID TableBID
-----------------
NULL 1
1 2
NULL 3 (not required)
NULL 2 (not required)
2 3
所需的结果是:
TableAID TableBID
-----------------
NULL 1
3 NULL (missing)
2 3
1 2
此查询的问题是,如果TableB.TableAID没有值,则TableA.IsStatic为true且没有任何匹配TableB行的表A行将永远不包括在内。此外,还包括一些TableB行,它们不应该包括在内
我能看到的唯一其他方法是使用联合
,而不存在
,但我希望以更有效的方式来实现这一点
更新:添加WHERE子句会删除“not required”行,但仍会忽略缺少的行
WHERE (b.TableBID IS NULL OR b.TableAID IS NULL OR b.TableAID = a.TableAID)
与where子句相同的查询的结果为:
TableAID TableBID
-----------------
NULL 1
1 2
2 3
真是令人心烦意乱。我认为这是另一种表达方式。您必须查看性能是否良好:
select a.TableAID, b.TableBID
from (select a.*
from @TableA a
join @TableC c
on c.TableCID = a.TableCID) a
full outer join (select b.*
from @TableB b
join @TableC c
on c.TableCID = b.TableCID) b
on b.TableAID = a.TableAID
where b.TableBID is not null or a.IsStatic = 1
我还应该提到,使用您提供的示例数据,很难确定上述查询是否真的符合您的要求。举例来说,如果我使用下面这个简单的查询来忽略@TableC
表,那么我仍然可以用您的示例数据得到正确的结果:
DECLARE @TableA TABLE (TableAID int, TableCID int, IsStatic bit)
DECLARE @TableB TABLE (TableBID int, TableAID int, TableCID int)
DECLARE @TableC TABLE (TableCID int)
INSERT INTO @TableC (TableCID) VALUES (1)
INSERT INTO @TableC (TableCID) VALUES (2)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (1, 1, 0)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (2, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (3, 2, 1)
INSERT INTO @TableA (TableAID, TableCID, IsStatic) VALUES (4, 2, 0)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (1, NULL, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (2, 1, 1)
INSERT INTO @TableB (TableBID, TableAID, TableCID) VALUES (3, 2, 2)
select a.TableAID, b.TableBID
from @TableA a
full outer join @TableB b
on b.TableAID = a.TableAID
where b.TableBID is not null or a.IsStatic = 1
编辑:评论中关于OP“要求”解释的有趣讨论。。。但如果我必须回答安东的观点:
select a.TableAID, b.TableBID
from (select a.*,
case when c.TableCID is not null then 1 end as has_c
from @TableA a
left join @TableC c
on c.TableCID = a.TableCID) a
full outer join (select b.*,
case when c.TableCID is not null then 1 end as has_c
from @TableB b
left join @TableC c
on c.TableCID = b.TableCID) b
on b.TableAID = a.TableAID
where (b.TableBID is not null or a.IsStatic = 1)
and (a.has_c = 1 or b.has_c = 1)
在你的连接中,试试这个。ISNULL上的联接表(table.column“”)=ISNULL(otherTable.column“”)。请原谅我的格式。我在手机上。联接用于将列合并到一行中。您正在尝试将行合并到单个结果集中。这就是工会的宗旨。如果只使用union,您的查询将更易于维护和理解。“你有什么理由要避开它吗?”迈克害怕承诺!(开玩笑……联盟,明白吗?)说真的,我想我必须在我想要避免的查询中有一个低效的
不存在。但是安东的回答避免了这一点,我只是想看看这是否对我有效。johna,答案已经提供了,请检查并标记为接受,如果是您想要的。如果我们更改了样本数据,则此脚本似乎不正确。尝试将TableB值(2,1,1)的插入替换为未显示的值(2,1,3)@Anton,(2,1,3)无效,因为Table3没有示例行ID值3。(1,2)正在为我显示。请参见要求。如果表A中有对应的记录,则不应使用表B的CID。只有表A的CID@john,没有外键约束的要求,因此形式上3是有效的,并且可以出现在表B中。根据您的要求,如果我们有(3),我们应该显示(1,2),因为表A仍然与表C有有效链接。此答案非常有效。然而,我接受了@sstan的回答,因为执行计划和速度更好(更多地是由于真实的数据结构和索引)。非常感谢您的回答,我可以确认它与真实的结构和数据完美配合。