2012-12-18 160 views
0

我有一個要求,只選擇有沒有交易的客戶,否則,他們的最後交易是在某個日期之後。SQL查詢太慢

目前,我的查詢時間太長。

有沒有更有效的方法來做到這一點?

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 

我希望我可以使用JOIN,但不知道....我需要在過去的2年內沒有交易的客戶,以及與交易的。

使用SQL Server 2008的

回答

1

你可以使用一個NOT EXISTS子句,這會給你空交易或指定日期之後沒有成交的結果,而無需任何最大值。

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) 
+0

這可能工作 - 但我不確定兩件事:1.爲什麼'SELECT NULL',而不是'SELECT *'? 2.這是否包括在Accs中有0行的客戶? – Craig

+0

@克雷格1.因爲它只是檢查「存在」,所以你不想從檢查中檢索任何一行。是的。 –

0

好了,你可以使用JOIN,只是它需要LEFT 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 

使用LEFT JOIN將返回來自客戶端無論所有記錄如果在ACC的表通訊員。

0

隨着加入,您可以:

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; 

但拉斐爾奧爾索斯的回答是最好的SQL,並且引擎知道用哈希來執行它加入(eventualy)。

+0

這看起來不錯 - 但它是否會包含沒有Accs行的客戶? – Craig

+0

是的,你會得到所有的客戶端,因爲它是'left join',但是如果你在'select'子句中添加列,你需要在'group by'子句中添加它們 –