【问题标题】:Left join if no data, otherwise Inner join无数据时左连接,否则内连接
【发布时间】:2012-08-20 16:56:44
【问题描述】:

我有一个视图 V 从几个表中选择数据。我还有一个表 T,它定义了允许用户查看 V 中哪种类型的数据。

对于用户而言,如果T中没有数据,则意味着他可以在我的视图V中看到所有内容,但如果中有数据T,那么我需要限制我的视图结果V

所以在我看来,如果 T 中没有任何内容,我需要执行 V Left join T 或如果 T 中有内容,我需要执行 V INNER JOIN T

但我不太确定如何编写此查询以获得可能的最佳性能(就服务器执行而言),提供视图 V 可能已经是一个不那么快的查询执行。我应该首先从 B 中选择所有内容并将其存储在某个变量或临时表中吗?还是可以使用我至今未听说过的巧妙的 SQL 语法轻松完成所有事情?

【问题讨论】:

  • 请显示样本数据和所需结果。你的单词问题是无形的,非常分散注意力。
  • 抱歉,我认为通过不深入细节来保持简单是一个更好的主意,但现在我明白你的意思了!

标签: sql-server join left-join inner-join


【解决方案1】:

与其关注问题的“内连接/外连接”部分,我建议分两步进行。

首先,您的应用程序可以查询表“T”以确定用户的访问权限。然后,其次,使用“T”中的数据来确定用户在“V”中可以访问的内容。

如果您正在编写一个同时控制数据库层和业务层的服务器应用程序,那么首先编写一个过程来收集所有用户的权限设置,然后执行两个查询之一 - 特权查询或非特权查询,取决于 T 的内容。

如果您必须在数据层中完成所有这些操作,请按以下步骤操作:

CREATE PROCEDURE myproc
    @current_user int
AS

-- Determine user's permission level
DECLARE @permission bit
SELECT @permission = permission FROM T WHERE t.user = @current_user

-- Use the appropriate query for this user
IF @permission IS NULL BEGIN
    SELECT * FROM V
END ELSE BEGIN
    SELECT * FROM V INNER JOIN T ON T.criteria=V.criteria
END

【讨论】:

    【解决方案2】:

    只有在你有一个在 T 中包含所有行的“默认”用户时才能使用内部连接来完成。否则你会遇到这样的事情:

    select V.*
    from V,
    T
    where (v.id = T.Id 
    AND T.User = current_user)
    OR NOT EXISTS (select 1 from T where T.user=current_user)
    

    【讨论】:

    • +1 因为这可行,但另一个答案看起来“更容易”适用于我的情况。非常感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 2017-08-15
    • 2010-10-06
    相关资源
    最近更新 更多