SQl任意或全部子句

SQl任意或全部子句,sql,sql-server,Sql,Sql Server,我有一个表,我查询该表以获得很少的列来将数据加载到应用程序 假设我在select查询中有以下列: Account| Employee | Amount | Position 123 | EMP123 | 1000 | 143 | EMP123 | 1000 | 153 | EMP123 | 1000 | 163 | EMP123 | 1000 | 100 | EMP456 | 1000 | 143 | EMP456

我有一个表,我查询该表以获得很少的列来将数据加载到应用程序

假设我在select查询中有以下列:

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
else
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
我使用任何子句都可以得到结果,但速度非常慢,我有超过100000条记录:|

我使用的查询

Select ACCOUNT,amount,EMPLOYEE,
  CASE 
  WHEN EMPLOYEE = ANY (SELECT EMPLOYEE FROM Table1 WHERE ACCOUNT = 123) 
  THEN 'Temp'
  ELSE 'Perm'
  END AS 'Position'
任何提示都将不胜感激

您可以在中使用

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

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

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

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

您可以尝试使用
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

此外,您可以在
帐户
员工
列上创建索引。

查询本身看起来并不不合理,这意味着任何重写都不太可能显著改变性能。正如Dmitry所说,现在是查看执行计划并查找错过的索引机会的时候了。除了调优(这是您应该研究的事情)之外,您还可以尝试重写
CASE
表达式以使用
EXISTS
子句。但是,这仍然可能给出相同的执行计划。您有超过100000条记录,如果它是唯一的,请尝试在account列上创建一个唯一索引。谢谢Zaynul,但当account为143时,这不会给我EMP123的正确位置。所以,我的意图是,如果员工有账户123的金额,则更新该员工所有事件的临时职位。谢谢Damien,我将测试此方法。谢谢大家的帮助。我最终创建了视图来简化事情,并使用michalquery来获取数据。因此,在15秒内大约有300000条记录。我认为这是合理的!!尽管应用程序所有者不同意:)
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