SQL查询太慢

SQL查询太慢,sql,sql-server-2008,query-optimization,Sql,Sql Server 2008,Query Optimization,我有一个要求,只选择没有交易的客户,或者,他们的最后一笔交易是在某个日期之后 目前,我的查询时间太长了 有没有更有效的方法 SELECT *, (SELECT MAX(AC_CLOSEDDAT) FROM Accs WHERE accs.AC_CLIENTCODE = c.CL_CLIENTCODE) AS LastTrans FROM Clients c WHERE CL_STATUS <> 'R' AND STORE_CODE = '69JX 我希望我能

我有一个要求,只选择没有交易的客户,或者,他们的最后一笔交易是在某个日期之后

目前,我的查询时间太长了

有没有更有效的方法

SELECT *, 
   (SELECT MAX(AC_CLOSEDDAT) FROM 
    Accs WHERE accs.AC_CLIENTCODE = c.CL_CLIENTCODE) AS LastTrans 
FROM Clients c 
WHERE CL_STATUS <> 'R' 
AND STORE_CODE = '69JX
我希望我能加入,但不确定。。。。我需要没有交易的客户,以及在过去两年内有交易的客户


使用SQL Server 2008。

您可以使用NOT EXISTS子句,它将为您提供给定日期后的空事务或无事务的结果,而不需要任何max

SELECT * FROM Clients c
WHERE CL_STATUS <> 'R'
AND STORE_CODE = '69JX'
AND NOT EXISTS 
    (SELECT NULL FROM Accs a
    WHERE a.AC_CLIENTCODE = c.CL_CLIENTCODE
    AND a.AC_CLOSEDDAT > theDateToCompare)

好的,您可以使用JOIN,只是它需要左JOIN:

SELECT c.*, MAX(AC_CLOSEDDAT) AS LastTrans
    FROM Clients c 
    LEFT JOIN Accs ON accs.AC_CLIENTCODE = c.CL_CLIENTCODE 
WHERE CL_STATUS <> 'R' 
    AND STORE_CODE = '69JX
使用左联接将从客户端返回所有记录,无论Accs表中是否有对应项。

使用联接,您可以:

SELECT c.client_id
FROM Clients c 
LEFT JOIN  Accs a
  on (a.AC_CLIENTCODE = c.CL_CLIENTCODE AND 
      a.AC_CLOSEDDAT >= DATEADD(year,-2,GETDATE())
WHERE CL_STATUS <> 'R'
AND STORE_CODE = '69JX'
group by c.client_id;

但是Raphaël Althaus的答案是最好的SQL,而且引擎知道最终使用哈希联合执行它。

这可能会起作用,但我不确定两件事:1。为什么选择空值而不是选择*?二,。这是否包括Accs中有0行的客户端?@Craig 1。因为这只是一个存在的检查,你不想从检查中检索任何行。2.是的。这看起来也不错-但它也会包括没有Accs行的客户端吗?是的,您将获得所有客户端,因为它是左联接,但是如果您在select子句中添加列,则还需要在group by子句中添加它们