Sql server SQL Server-选择不同的备选查询

Sql server SQL Server-选择不同的备选查询,sql-server,select,distinct,Sql Server,Select,Distinct,我之前问过一个问题,关于使用SELECT DISTINCT进行替换,因为执行查询需要更长的时间。有人建议我使用EXISTS,它在0秒执行时比之前的44秒执行时工作得更好。我不太熟悉查询语法,但正在学习。我希望有人能够在不使用DISTINCT和EXISTS的情况下重新表述以下查询,因为它以前工作得很好。谢谢你的帮助 select distinct EM.Employee, rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName)

我之前问过一个问题,关于使用SELECT DISTINCT进行替换,因为执行查询需要更长的时间。有人建议我使用EXISTS,它在0秒执行时比之前的44秒执行时工作得更好。我不太熟悉查询语法,但正在学习。我希望有人能够在不使用DISTINCT和EXISTS的情况下重新表述以下查询,因为它以前工作得很好。谢谢你的帮助

select distinct EM.Employee, 
                rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName) as Name 
from EM EM 
inner join PR PR 
    on EM.Employee = PR.ProjMgr 
where PR.WTS1 in (Select distinct WTS1 
                  from TabFields 
                  where custInclude = 'Y' and WTS2 = '') 
    and PR.WTS2 = '' 
order by Name

我觉得这个问题很好。它跑得慢吗? 你真的需要修剪名字和姓氏吗?如果没有,你可以忽略它们

 select distinct E.Employee, rtrim(E.FirstName) + ' ' + rtrim(E.LastName) as Name 
 from EM E join PR P on E.Employee = P.ProjMgr 
 where P.WTS1 in (Select WTS1 from TabFields where custInclude = 'Y' and WTS2 = '') 
   and P.WTS2 = '' 
 order by Name
Exists可用于在执行其他SQL之前检查某个条件。
如果您需要不同的行,exists将不起作用。

如果您正在计算子查询,新查询优化器将以与exists相同的方式处理

由于在中使用,因此在子查询中不需要使用DISTINCT。把它拿出来


看起来好像有人在写查询,并且总是使用DISTINCT,这是一个非常糟糕的习惯。应仅使用DISTINCT以避免重复。没有理由消除子查询中的重复,因为说1在1,2,1,3中与说1在1,2,3中一样准确。

加入时,得到的是部分笛卡尔积。部分连接来自内部连接条件

因此,对于EM中分别有3行和4行PR的2行,您将在输出中得到7行。正如所料。你要求给我所有匹配行的EM和PR的部分笛卡尔积

但是,您需要在EM中给我行,其中PR中有一些内容。因此内部连接是错误的构造

您可以在其他情况下使用IN、EXISTS或INTERSECT,对于后一个问题,它们在语义上都是正确的

在这种情况下,您使用In的位置不正确。正如我前面所说的,整个测试条件应该被推到子查询中

所以,这两个都是正确的

FROM子句中的一个表 子查询中的所有条件 不清楚 停止加入

select
    EM.Employee, rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName) as Name 
from
    EM EM 
WHERE
   EXISTS (SELECT *
       FROM
          PR PR 
          JOIN
          TabFields TF ON PR.WTS1 = TF.WTS1
       WHERE
          PR.WTS2 = '' AND
          TF.custInclude = 'Y' and TF.WBT2 = '' AND
          EM.Employee = PR.ProjMgr
          )

select
    EM.Employee, rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName) as Name 
from
    EM EM 
WHERE
   EM.Employee IN (SELECT PR.ProjMgr
       FROM
          PR PR 
          JOIN
          TabFields TF ON PR.WTS1 = TF.WTS1
       WHERE
          PR.WTS2 = '' AND
          TF.custInclude = 'Y' and TF.WBT2 = ''
       )
使用2个更接近原始查询的INs:

select EM.Employee, 
                rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName) as Name 
from EM EM 
WHERE 
      EM.Employee IN (SELECT PR.ProjMgr
          FROM 
            PR PR 
          where PR.WTS1 in (Select distinct WTS1 
                  from TabFields 
                  where custInclude = 'Y' and WTS2 = '') 
            and PR.WTS2 = ''
       ) 
order by Name

下面的代码中不需要使用distinct

select  EM.Employee, 
                rtrim(EM.FirstName) + ' ' + rtrim(EM.LastName) as Name 
from EM 
inner join PR 
    on EM.Employee = PR.ProjMgr 
where exists (Select * 
                  from TabFields 
                  where custInclude = 'Y' and WTS2 = '' and PR.WTS1 = tabfields.WTS1 ) 
    and PR.WTS2 = '' -- Comment: Check if this clause is covered by the subquery and can be ommited
order by Name

尝试使用“分组依据”而不是“选择不同”。还可以从WHERE子句中移动子查询,并将其用作联接中的派生表

SELECT EM.Employee, 
       RTRIM(EM.FirstName) + ' ' + RTRIM(EM.LastName) AS Name 
FROM EM EM 
INNER JOIN PR PR 
    ON EM.Employee = PR.ProjMgr 
INNER JOIN (SELECT WTS1 
              FROM TabFields 
             WHERE custInclude = 'Y' AND WTS2 = ''
             GROUP BY WTS1) x
    ON PR.WTS1 = x.WTS1
    AND PR.WTS2 = '' 
GROUP BY EM.Employee,    RTRIM(EM.FirstName) + ' ' + RTRIM(EM.LastName) 
ORDER BY RTRIM(EM.FirstName) + ' ' + RTRIM(EM.LastName)

你应该试着理解上一个问题的答案,并把它应用到这个问题上。如果你只是简单地将论坛上的答案复制粘贴到你的代码中,而不是试图理解,那么你正朝着成为一个代码猴子的方向滑向下坡…+1000000000000000向Remus指出,理解你正在做的事情更为重要。这是同一个问题,但你之前做过的事情是经过净化的吗?仅供参考:这是在同一数据库上使用的另一个查询。我尝试了一下您的查询,gbn,它在0秒内完美运行。我希望将相同的结构应用到上面的查询中,但遇到了一些问题。是的,它运行缓慢,所以我一直在尝试优化它。上面的第一个查询需要37秒才能执行。EM表中有多少行?第二个需要多长时间?两个查询都是相同的,只是第二个查询使用联接而不是子查询。第二个查询在0秒内执行,但返回143行,而我只希望返回33行。您编写的第一个示例还返回33。正如JNK所指出的,不需要在内部子查询上使用distinct。这可能会让它快一点。你现在能试试吗?我试着不使用DISTINCT运行,但它拉了数千行,因为它拉的是重复的。不幸的是,对于这个场景,我要求它只提取唯一的值。谢谢。我没有编写原始查询,正在修改其他人创建的现有查询。我真的很感谢你的帮助。再次感谢。