2014-06-05 65 views
0

我有兩個SQL Server表。第一個表格是客戶表格,其中包含客戶編號,姓名等。第二個表格包含客戶的服務日期。客戶可以有多個服務日期。以下是服務日期表的示例:如何在存在多個記錄時使用MIN和MAX選擇記錄?

custnmbr  DateIn  DateOut 
------------------------------------  
78001  1991-02-10 2001-12-07 
78001  2002-08-03 2003-06-17 
78001  2006-11-22 NULL 

我想選擇最早的DateIn和最近的DateOut。在上面的例子中,我想以1991-02-10的形式返回DateIn,並且由於客戶當前處於活動狀態,因此我希望將DateOut返回爲NULL。

這是我已經盡力了,但沒有運氣

SELECT 
    SM.Custnmbr, 
    CONVERT (VARCHAR(10), MAX(LH.DateIn), 101) AS DateIn, 
    CONVERT (VARCHAR(10), MAX(LH.DateOut), 101) AS DateOut, 
FROM  
    dbo.toCustomer SM 
LEFT OUTER JOIN 
    dbo.toLocCustHist LH ON SM.CustomerId = LH.CustomerId 
GROUP BY  
    SM.CustNmbr, SM.CustName, LH.LocationId 

當我運行查詢DateIn是1991年2月10日是正確的,但DateOut具有2003-06-17,這是錯誤的。

回答

0
WITH TEMP AS 
(
SELECT SM.Custnmbr AS Custnmbr, 
CONVERT (VARCHAR(10), MIN(LH.DateIn), 101) AS DateIn, 
CONVERT (VARCHAR(10), MAX(ISNULL(LH.DateOut,'9999-12-12')), 101) AS DateOut, 
FROM dbo.toCustomer SM 
LEFT OUTER JOIN dbo.toLocCustHist LH ON SM.CustomerId = LH.CustomerId 
GROUP BY SM.CustNmbr, SM.CustName, LH.LocationId 
) 
SELECT Custnmbr,DateIn, 
CASE WHEN DateOut='9999-12-12' THEN NULL 
ELSE DateOut 
END 
FROM TEMP; 
2

NULL值不聚集函數考慮的,所以你需要設置NULL到別的東西,你不應該在你的GROUP BY聲明中多餘的元素:

SELECT 
    SM.Custnmbr, 
    CONVERT (VARCHAR(10), MAX(LH.DateIn), 101) AS DateIn, 
    CONVERT (VARCHAR(10), MAX(ISNULL(LH.DateOut,'2099-01-01'), 101) AS DateOut, 
FROM  
    dbo.toCustomer SM 
LEFT OUTER JOIN 
    dbo.toLocCustHist LH ON SM.CustomerId = LH.CustomerId 
GROUP BY  
    SM.CustNmbr 
+0

組中的額外元素可能是相關的,具體取決於整個查詢的外觀。例如,如果幾個人在多個地點工作並且他們在每個地點使用不同的機器會發生什麼。也許我們需要與每個位置相關的數據,但我們並不關心位置本身。將客戶名稱包含在組中可能是適當的,但不包括在選擇中。 – Jenn

+0

@Jenn我不確定什麼情況下顯示相同的'Custnmbr'多次與相關的MAX()'日期是無關的,但可能會有這種情況。 –

+1

這很少見,我不認爲我的例子完全覆蓋了它。我已經看到用作摘要的存儲過程,他們使用這個技巧。例如,也許我正在撤回一份彙總信息,通知IT部門過去一年中已提供服務的機器數量以及解決問題所需的平均時間。在這種情況下,最有可能的是該組中的列不在選擇中。 – Jenn

0

SQL不考慮一個NULL日期大於2003-06-17。您需要用MAX()來替換NULL,並將其替換爲未來的佔位符日期。

SELECT SM.Custnmbr, 
CONVERT (VARCHAR(10), MAX(LH.DateIn), 101) AS DateIn, 
CONVERT (VARCHAR(10), MAX(ISNULL(LH.DateOut,'99991231'), 101) AS DateOut, 
FROM dbo.toCustomer SM 
LEFT OUTER JOIN dbo.toLocCustHist LH ON SM.CustomerId = LH.CustomerId 
GROUP BY SM.CustNmbr, SM.CustName, LH.LocationId 

如果你想顯示當前的日期(即GETDATE()),而不是9999-12-31,可以使用CASE語句。