如何根据某些条件完成SQL连接?
我有两张桌子:如何根据某些条件完成SQL连接?,sql,sql-server,left-join,Sql,Sql Server,Left Join,我有两张桌子: CREATE TABLE Users( UserId UNIQUEIDENTIFIER NOT NULL PRIMARY KEY, UserName NVARCHAR(200) NOT NULL, -- some other columns CurrentSubscriptionId UNIQUEIDENTIFIER NULL, ) CREATE TABLE Subscriptions( SubscriptionId UNIQUEIDEN
CREATE TABLE Users(
UserId UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
UserName NVARCHAR(200) NOT NULL,
-- some other columns
CurrentSubscriptionId UNIQUEIDENTIFIER NULL,
)
CREATE TABLE Subscriptions(
SubscriptionId UNIQUEIDENTIFIER NOT NULL PRIMARY KEY,
UserId UNIQUEIDENTIFIER NOT NULL,
-- some other columns
)
我有一个存储过程,用于检索“用户”列表及其“当前订阅”:
关键是,对于存储过程的某些调用,我只需要来自“订阅”的数据,而不需要来自其他调用的数据。因此,我将向存储过程中添加一个@includeSubscriptionData
位参数(这是伪代码,我必须单独列出每个有条件包含的列):
希望能避免加入。所以我先试试这个:
DECLARE @includeSubscriptionData BIT;
SET @includeSubscriptionData=0;
SELECT List-Of-Columns-FromUsers,
CASE WHEN @includeSubscriptionData THEN SubscriptionId ELSE NULL END
FROM Users LEFT OUTER JOIN Subscriptions ON
Users.CurrentSubscriptionId=Subscriptions.SubscriptionId
WHERE SomeConditionOnUsers
该计划显示,仍然可以访问“订阅”
当位设置为零时,如何取消对第二个表的访问?是否尝试将其放入联接条件中
DECLARE @includeSubscriptionData BIT;
SET @includeSubscriptionData=0;
SELECT List-Of-Columns-FromUsers,
SubscriptionId
FROM Users LEFT OUTER JOIN Subscriptions ON
Users.CurrentSubscriptionId=Subscriptions.SubscriptionId and @includeSubscriptionData = 1
WHERE SomeConditionOnUsers
OPTION(RECOMPILE)
方法1-控制流
方法2-修改联接
您可以使用IF/ELSE进行此操作
DECLARE @includeSubscriptionData BIT;
SET @includeSubscriptionData=0;
IF @includeSubscriptionData == 0
BEGIN
SELECT List-Of-Columns-FromUsers
FROM Users WHERE SomeConditionOnUsers
END
ELSE
BEGIN
SELECT List-Of-Columns-FromUsers
FROM Users LEFT OUTER JOIN Subscriptions ON Users.CurrentSubscriptionId=Subscriptions.SubscriptionId
WHERE SomeConditionOnUsers
END
这样,我必须维护列列表两次。我尝试了第二种方法-仍然可以访问第二个表。@sharptooth你不能两全其美,我的朋友
;-)代码>@sharptooth P.S.最终,我觉得第一种方法对你来说是最好的解决方案。如果您唯一的抱怨是您必须维护两列列表:这不是一个有效的理由。惰性代码=糟糕的代码;-)代码>@sharptooth可能值得一读:是的,我试过了-仍然可以访问第二个表。添加重新编译查询提示。编辑设置。是的,提示访问是有条件的。我不确定这个提示是否有负面影响。是的,第二个表将出现在查询计划中。但是,如果查看计划中的“实际行数”值,它将为零,即不执行IO。在我的测试中,添加该查询提示实际上会使第二个表不出现在查询计划中。YMMV SQL访问表订阅
到底有什么问题?我唯一的想法是避免接触订阅
表,通过动态SQL构建查询,但这本身就有很多问题。@NickyvV该查询运行时间更长,并且会增加服务器上的负载。可能会引起一些兴趣,因此我认为CurrentSubscriptionID至少需要是一个FK
DECLARE @includeSubscriptionData BIT;
SET @includeSubscriptionData=0;
SELECT List-Of-Columns-FromUsers,
SubscriptionId
FROM Users LEFT OUTER JOIN Subscriptions ON
Users.CurrentSubscriptionId=Subscriptions.SubscriptionId and @includeSubscriptionData = 1
WHERE SomeConditionOnUsers
OPTION(RECOMPILE)
IF @includeSubscriptionData = 1
BEGIN
SELECT list
, of
, columns
FROM Users
INNER
JOIN Subscriptions
ON Users.CurrentSubscriptionId = Subscriptions.SubscriptionId
WHERE SomeConditionOnUsers
;
END
ELSE
BEGIN
SELECT list
, of
, columns
FROM Users
;
END
;
SELECT list
, of
, columns
FROM Users
LEFT
JOIN Subscriptions
ON Users.CurrentSubscriptionId = Subscriptions.SubscriptionId
AND @includeSubscriptionData = 1
WHERE SomeConditionOnUsers
DECLARE @includeSubscriptionData BIT;
SET @includeSubscriptionData=0;
IF @includeSubscriptionData == 0
BEGIN
SELECT List-Of-Columns-FromUsers
FROM Users WHERE SomeConditionOnUsers
END
ELSE
BEGIN
SELECT List-Of-Columns-FromUsers
FROM Users LEFT OUTER JOIN Subscriptions ON Users.CurrentSubscriptionId=Subscriptions.SubscriptionId
WHERE SomeConditionOnUsers
END