2010-09-29 51 views
1

我最近一直在反覆地遇到以下情況,要麼我需要將MAX()或SUM()應用於表上的一列,但我需要爲其他列設置DISTINCT值集。如何將sql聚合函數與獨特的更清晰地結合起來?

例如,考慮下表和表示登錄到StackOverflow的詳細信息的相關列。

SoUserLogins(OpenIdToken,名稱,IpAdress,LoginTimeStamp,QuestionsAsked)

我可能要包含用戶和他們的最後一次登錄的結果集。

SELECT DISTINCT 
    OpenIdToken, 
    MAX(LoginTimeStamp) 
INTO #tmpLastLogin 
FROM SoUserLogins 
GROUP BY OpenIdToken 

但我需要不同的值從其他列。我將把它包裝在一個公共表格表達式(CTE)中,因爲我稍後會使用它,並且不想清理另一個臨時表。

;WITH tmpLastLogin_CTE AS (
SELECT DISTINCT 
    SOL.OpenIdToken, SOL.Name, SOL.IpAdress, SOL.QuestionsAsked 
    TTL.LastLogin 
FROM SoUserLogins SOL 
JOIN #tmpLastLogin TLL ON SOL.OpenIdToken = TLL.OpenIdToken 
) 
--Extra SQL using tmpLastLogin_CTE goes here 

你可以改變MAX(LoginTimeStamp)總結(QuestionsAsked)在上面的代碼有一些額外的調整,以看到類似的例子。

我的問題,是否有更清潔或更優雅的方式來處理這些情況?

我正在使用SQL Server。

+0

我建議刪除第一個查詢DISTINCT關鍵字,因爲它是多餘的,令人困惑 - GROUP BY子句確保只有不同OpenIdToken的值將返回。 – 2010-09-30 12:49:52

回答

7

你的意思是?

SELECT DISTINCT 
    SOL.OpenIdToken, SOL.Name, SOL.IpAdress, SOL.QuestionsAsked, 
    MAX(LoginTimeStamp) OVER (PARTITION BY OpenIdToken) AS LastLogin 
FROM SoUserLogins SOL 

所以你必須每OpenIdToken和相同LastLogin值將被重複的一組中的所有行多行?

+0

我想這可能是我想要去的方式。我認爲它不適用於多列的分區依據,即(分區由OpenIdToken,IpAddress),但我很高興錯誤。 – 2010-09-30 13:33:25

0

如果您正在Oracle數據庫你應該考慮使用自定義 * 甲骨文分析功能 * 這讓您根據一列列agreggate您的數據。

在我寫這篇文章時,馬丁做了答案。

但一些文件可以發現here(法語)

+0

我想托馬斯正在使用SQLServer的一個版本,基於插入到臨時表中。我知道最新版本的SQLServer確實有類似的分析功能。 – 2010-09-30 12:51:54

+1

我正在使用SQL Server。我會更新這個問題來反映這一點。 – 2010-09-30 13:17:16

+1

@Mark - 是的。如果OP位於支持CTE(2005+)的SQL Server版本上,則它們也將支持支持這些功能的版本。 – 2010-09-30 13:22:43