SQl ANY或ALL子句

时间:2018-09-18 07:02:43

标签: sql sql-server

我有要查询的表,以获取几列以将数据加载到应用程序。

假设我在选择查询中有以下几列:

Account| Employee | Amount | Position
123    | EMP123   | 1000   |
143    | EMP123   | 1000   |
153    | EMP123   | 1000   |
163    | EMP123   | 1000   |
100    | EMP456   | 1000   |
143    | EMP456   | 1000   |
153    | EMP456   | 1000   |
163    | EMP456   | 1000   |

我想根据帐户123选择员工的职位。

因此,对于所有在记录中拥有帐户123的雇员,其职位都将返回,例如Temp以及其他Perm

根据上述示例的预期输出;

Account| Employee | Amount | Position
123    | EMP123   | 1000   | Temp
143    | EMP123   | 1000   | Temp
153    | EMP123   | 1000   | Temp
163    | EMP123   | 1000   | Temp
100    | EMP456   | 1000   | Perm
143    | EMP456   | 1000   | Perm
153    | EMP456   | 1000   | Perm
163    | EMP456   | 1000   | Perm

我使用ANY子句得到了结果,但这非常非常非常慢,并且我有超过100000条记录:|

我使用的查询;

Select ACCOUNT,amount,EMPLOYEE,
  CASE 
  WHEN EMPLOYEE = ANY (SELECT EMPLOYEE FROM Table1 WHERE ACCOUNT = 123) 
  THEN 'Temp'
  ELSE 'Perm'
  END AS 'Position'

任何提示将不胜感激!

5 个答案:

答案 0 :(得分:1)

这是一个使用窗口聚合的示例:

declare @t table(Account int, Employee char(6), Amount int)
insert into @t(Account, Employee, Amount) values
(123,'EMP123',1000),
(143,'EMP123',1000),
(153,'EMP123',1000),
(163,'EMP123',1000),
(100,'EMP456',1000),
(143,'EMP456',1000),
(153,'EMP456',1000),
(163,'EMP456',1000)

select
    *,
    MAX(CASE WHEN Account='123' THEN 'Temp' ELSE 'Perm' END) OVER (PARTITION BY Employee)
from @t
正如我在评论中所说,

令人怀疑的是,任何重写都将大大提高性能,并且很可能缺少适当的索引。如果它太过惊人,则当您为任一查询(问题中的一个或此处的一个)生成执行计划时,系统应突出显示缺少的索引 1

结果:

Account     Employee Amount      
----------- -------- ----------- ----
123         EMP123   1000        Temp
143         EMP123   1000        Temp
153         EMP123   1000        Temp
163         EMP123   1000        Temp
100         EMP456   1000        Perm
143         EMP456   1000        Perm
153         EMP456   1000        Perm
163         EMP456   1000        Perm

1 请注意,建议并非总是如此,我们该怎么说。但是,如果说缺少索引,通常 some 个额外的索引会缩短查询时间,这是正确的。但是不要盲目地应用所有这些建议。

答案 1 :(得分:0)

您可以在其中使用

Select ACCOUNT,amount,EMPLOYEE,
  CASE 
  WHEN EMPLOYEE in (SELECT EMPLOYEE FROM Table1 WHERE ACCOUNT = 123) 
  THEN 'Temp'
  ELSE 'Perm'
  END AS 'Position'

答案 2 :(得分:0)

  Select ACCOUNT,amount,EMPLOYEE,
  CASE 
  WHEN EMPLOYEE like '%123%' then 'temp' else 'perm' end as position
  from t 

答案 3 :(得分:0)

尝试此查询。

SELECT ACCOUNT,amount,EMPLOYEE
, CASE WHEN ISNULL(T2.HasAnyPosition, 0) > 0 THEN 'Perm' 
ELSE 'Temp' END AS Position
FROM EmployeeTable T1
OUTER APPLY
(
 SELECT COUNT(0) HasAnyPosition
 From PositionTable T2
 WHERE T2.Account = T1.Account
) T2

答案 4 :(得分:0)

您可以尝试使用exists

select Account,
       Employee,
       Amount,
       case when exists(select 1 from my_table
                        where Employee = t.Employee
                          and Account = 123)
            then 'Temp' else 'Perm' end Position
from my_table t

此外,您可以在AccountEmployee列上创建索引。