2012-02-16 19 views
1

在我用,我有個約會,工作數據的每一行和值:通過TSQL確定一個月中任意最新的一天?

f1       f2 
2012-01-01 00:00:00.000  10 
2012-01-10 00:00:00.000  9 
2012-02-01 00:00:00.000  19 
2012-02-15 00:00:00.000  31 

使用TSQL,我需要返回包含最新DAY具體年月組合的每一行 - 例如,在上面的數據中,我需要返回自2012年1月10日以來存儲的2012年1月「最新」日的第2行和第4行,2012年2月15日是2012年2月15日的最新日期。預期效果:

f1       f2 
2012-01-10 00:00:00.000  9 
2012-02-15 00:00:00.000  31 

注意,這不是簡單地確定「每月的最後一天」或「每月的最後一個工作日」一樣簡單。

我懷疑我需要使用某種GROUP BY組合,其中包含MAX在datepart(「day」,f1)上的組合,但我在如何前進方面處於虧損狀態。有人能把我推向正確的方向嗎?

+0

請註明您所使用的SQL Server版本。 – 2012-02-16 03:08:39

+0

你在給定的日期有多行記錄嗎? – 2012-02-16 03:37:09

+0

@JohnDewey提供了一個很好的觀點 - 如果第3和第4行的日期相同,你打算怎麼打破這個關係?即使您不在意,您也需要告訴SQL Server哪一行,否則每次運行查詢時可能會得到不同的結果。 – 2012-02-16 03:43:39

回答

3

這是假設,因爲其他人指出,對於F1的值是您的集內不同。

SELECT 
    MaxValues.f1, 
    Detail.f2 
FROM 
    (
    SELECT 
     DATEPART(year, f1), 
     DATEPART(month, f1), 
     MAX(f1) AS f1 
    FROM 
     MyTable 
    GROUP BY 
     DATEPART(year, f1), 
     DATEPART(month, f1) 
    ) AS MaxValues 
    INNER JOIN MyTable AS Detail ON 
     Detail.f1 = MaxValues.f1 
+0

我認爲這將很好地工作,因爲我與仍然在2K運行......我記得工作的傢伙,2000不支持嵌套子查詢這個樣子。 – 2012-02-16 11:13:53

+0

@RussellChristopher - 我相信在後期版本中,這可能會優化以刪除JOIN。 – 2012-02-16 13:15:03

+0

@RussellChristopher感謝您的接受。順便說一句,我把你的評論關於「會很好地工作」和「因爲這個人...仍然在2K上運行」,這意味着這可能是某種被棄用的功能。這是一個香草衍生的表格,大多數RDBMS支持這一點。弱者不這樣做。這個語法在MSSQL Server中起作用,因爲我記得很久以前。它不僅在2000年工作,還在2005年,2008年和2008年R2工作。它也沒有嵌套。 – 2012-02-21 19:57:33

5

假設SQL Server 2005或更好:

DECLARE @t TABLE (f1 DATETIME, f2 INT); 

INSERT @t SELECT '2012-01-01',10 
UNION ALL SELECT '2012-01-10',9 
UNION ALL SELECT '2012-02-01',19 
UNION ALL SELECT '2012-02-15',31; 

;WITH x AS 
(
    SELECT f1, f2, ROW_NUMBER() OVER (
    PARTITION BY DATEADD(MONTH, DATEDIFF(MONTH, 0, f1), 0) 
    ORDER BY f1 DESC) AS rn 
    FROM @t 
) 
SELECT f1, f2 FROM x 
WHERE rn = 1; 
+0

PARTITION BY DATEADD(月,DATEDIFF(MONTH,0,F1),0),......可能已經減少到PARTITION BY DATEDIFF(MONTH,0,F1))...,它仍然是正確的想法+1 – 2012-02-16 09:08:18

+0

@ t-clausen.dk這是一個很好的觀點,我習慣於在太多次必須回答爲什麼我只是在一個整數上進行分組之後才包括這兩個詞。 :-) – 2012-02-16 12:47:28

0

或者更少

SELECT f1, f2 
FROM (SELECT f1, f2, MAX(f1) OVER(PARTITION BY YEAR(f1), MONTH(f1)) AS f3 FROM @t) t 
WHERE f1 = f3 
相關問題