首页 > 解决方案 > SQl ANY 或 ALL 子句

问题描述

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

假设我有来自选择查询的以下列:

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   |

我想根据 account 选择员工的职位123

因此,对于所有123在记录中拥有帐户的员工,请返回他们的职位,例如Tempelse 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'

任何提示将不胜感激!

标签: sqlsql-server

解决方案


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

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请注意,这些建议并不总是(怎么说)一流。但是,如果它说缺少索引,通常一些额外的索引会改善您的查询时间是正确的。但不要盲目地应用所有这些建议。


推荐阅读