SQL-如何优化查询

SQL-如何优化查询,sql,sql-server,optimization,Sql,Sql Server,Optimization,我编写了以下查询,提取当前用户部门的子部门中的所有用户。 当前用户来自客户端应用程序,但出于测试原因,我在SQL中将其标记在这里 DECLARE @UserID INT = 72 SELECT * FROM users WHERE Department_Id IN ( SELECT DISTINCT Id /*, idp*/ FROM departments

我编写了以下查询,提取当前用户部门的子部门中的所有用户。 当前用户来自客户端应用程序,但出于测试原因,我在SQL中将其标记在这里

DECLARE @UserID INT = 72

SELECT * 
FROM users
WHERE Department_Id IN ( 
                        SELECT DISTINCT Id    /*, idp*/
                        FROM departments
                        WHERE idp IN (
                                        SELECT Department_Id 
                                        FROM users 
                                        WHERE Id = @UserID
                                        )
                        )

OR Department_Id IN (
                        SELECT DISTINCT idp
                        FROM departments
                        WHERE idp IN (
                                        SELECT Department_Id 
                                        FROM users 
                                        WHERE Id = @UserID
                                        )
                        )
我想从部门中选择Ididp进行简短查询,但当我使用这种方式时,它会返回一个SQL错误:

当子查询未引入EXISTS时,只能在选择列表中指定一个表达式

这是因为我的列表应该只包含一列,而不是两列

请告诉我减少此查询的任何方法,特别是第二部分(在之后),它是第一部分(在之前)的复制粘贴


谢谢。

试着像这样使用
EXISTS

SELECT * 
FROM   users u
WHERE  EXISTS(  SELECT *
                FROM   departments
                WHERE  idp IN (SELECT Department_Id FROM users WHERE Id = @UserID)
                       AND (id = u.Department_Id
                           OR idp = u.Department_Id)    )

尝试像这样使用
EXISTS

SELECT * 
FROM   users u
WHERE  EXISTS(  SELECT *
                FROM   departments
                WHERE  idp IN (SELECT Department_Id FROM users WHERE Id = @UserID)
                       AND (id = u.Department_Id
                           OR idp = u.Department_Id)    )
一些想法

  • 嵌套在子查询中不太可能友好
  • 在中使用时不需要区分
  • 我会使用GROUP BY来处理1:多的关系,但由于您的答案是使用另一种结构,我会尽量接近您所拥有的

    DECLARE @UserID INT = 72
    
    SELECT
      *
    FROM
      users AS associates
    WHERE
      EXISTS (
        SELECT 
          *
        FROM
          users
        INNER JOIN      
          departments
            ON departments.idp = users.Department_Id
        WHERE
          users.id = @user_id
          AND (   departments.id  = associates.department_id
               OR departments.idp = associates.department_id)
      )
    
    如果您确实使用了分组方式,则可以避免子查询和相关子查询一起使用

    DECLARE @UserID INT = 72
    
    SELECT
      associates.id
    FROM
      users
    INNER JOIN      
      departments
        ON departments.idp = users.Department_Id
    INNER JOIN
      users AS associates
        ON associates.department_id = departments.id
        OR associates.department_id = departments.idp
    WHERE
      users.id = @user_id
    GROUP BY
      associates.id
    
    如果在
    associates
    中有您需要的任何其他字段,只需将它们添加到选择分组依据中。

    一些想法

  • 嵌套在子查询中不太可能友好
  • 在中使用时不需要区分
  • 我会使用GROUP BY来处理1:多的关系,但由于您的答案是使用另一种结构,我会尽量接近您所拥有的

    DECLARE @UserID INT = 72
    
    SELECT
      *
    FROM
      users AS associates
    WHERE
      EXISTS (
        SELECT 
          *
        FROM
          users
        INNER JOIN      
          departments
            ON departments.idp = users.Department_Id
        WHERE
          users.id = @user_id
          AND (   departments.id  = associates.department_id
               OR departments.idp = associates.department_id)
      )
    
    如果您确实使用了分组方式,则可以避免子查询和相关子查询一起使用

    DECLARE @UserID INT = 72
    
    SELECT
      associates.id
    FROM
      users
    INNER JOIN      
      departments
        ON departments.idp = users.Department_Id
    INNER JOIN
      users AS associates
        ON associates.department_id = departments.id
        OR associates.department_id = departments.idp
    WHERE
      users.id = @user_id
    GROUP BY
      associates.id
    

    如果在
    associates
    中有任何您需要的其他字段,只需将它们添加到SELECTGROUP BY中。

    Hiya,您可以在同一语句中有多个distinct,请参见此处--希望这有帮助,谢谢。这不是关于优化查询性能,而是关于“优化”查询语法,对吗?@Branko Dimitrijevic,是的-你是对的:)Hiya,你可以在同一个语句中有多个distinct,请看这里--希望这有帮助,谢谢这不是关于优化查询性能,而是关于“优化”查询语法,对吗?@Branko Dimitrijevic,是的-你是对的:)@Indikaf,此查询只返回一个作为父项的项。我发现wqw提供的答案是好的answer@Indikaf,此查询仅返回一个作为父项的项。我发现wqw提供的答案是一个很好的答案。要进一步减少代码行数,您可以在exists子查询中用
    u.Department\u id(id,idp)
    替换
    和(id=u.Department\u id或idp=u.Department\u id)
    。要进一步减少代码行数,您可以替换
    和(id=u.Department\u id或idp=u.Department\u id)
    在(id,idp)中的u.Department\u id存在于exists子查询中。