2013-01-08 41 views
1

嗨,大家好,我是SQL初學者,所以請耐心等待...... :)SQL Server 2008如何使用GROUP(ing)其他列選擇具有值的行?

我的問題如下。

我得到這個表:

 DateTime   ID  Year Month Value Cost 
-------------------|------|--------|-------|-------|--------| 
1-1-2013 00:00:01 | 1 | 2013 | 1 | 30 | 90 | 
1-1-2013 00:01:01 | 1 | 2013 | 1 | 0 | 0 | 
1-1-2013 00:02:01 | 1 | 2013 | 1 | 1 | 3 | 
1-2-2013 00:00:01 | 1 | 2013 | 2 | 2 | 6 | 
1-2-2013 00:01:01 | 1 | 2013 | 2 | 3 | 9 | 
1-2-2013 00:02:01 | 1 | 2013 | 2 | 4 | 12 | 
1-3-2013 00:00:01 | 1 | 2013 | 3 | 5 | 15 | 
1-3-2013 00:01:01 | 1 | 2013 | 3 | 6 | 18 | 
1-3-2013 00:02:01 | 1 | 2013 | 3 | 7 | 21 | 

現在我想要得到的是這樣的結果

Year Month Value Cost 
|--------|-------|-------|--------| 
| 2013 | 1 | 1 | 3 | 
| 2013 | 2 | 4 | 12 | 
| 2013 | 3 | 7 | 21 | 

正如你可以看到我想要GROUP BY的[月]和[年]並獲取每個[月]的最後[值]。

現在,你可以從結果明白我不嘗試從[數值]列中的MAX()值,但對於每一個[月]的最後一個值,這是我的問題..

謝謝提前

PS
我可以GROUP BY [Year]和[Month],但據我所知當我添加[Value]列時,GROUP BY不會影響結果,因爲SQL需要更多特化你值什麼SQL得到..

回答

0

因爲你使用SQL Server 2008,你可以使用row_number()得到結果:

select year, month, value, cost 
from 
(
    select year, month, value, cost, 
    row_number() over(partition by year, month order by datetime desc) rn 
    from yourtable 
) src 
where rn = 1 

SQL Fiddle with Demo

或者你可以使用子查詢得到這個(注:這個版本,如果你有一個以上的記錄,每月相同的最高datetime那麼你將返回每個記錄:

select t1.year, t1.month, t1.value, t1.cost 
from yourtable t1 
inner join 
(
    select max(datetime) datetime 
    from yourtable 
    group by year, month 
) t2 
    on t1.datetime = t2.datetime 

SQL Fiddle with Demo

均可以得到相同的結果:

| YEAR | MONTH | VALUE | COST | 
------------------------------- 
| 2013 |  1 |  1 | 3 | 
| 2013 |  2 |  4 | 12 | 
| 2013 |  3 |  7 | 21 | 
+0

謝謝!這很有幫助,我用你的第一個樣本,我確切地知道我需要什麼。歡呼m8。 – BujinRikimaru

1

而不是使用row_number()的,你也可以使用rank()。使用rank()可能會在同一年和同一月內爲您提供多個值,請參見this post。 因此,添加了一個group。

SELECT 
    [Year], 
    [Month], 
    [Value], 
    [Cost] 
FROM 
(
    SELECT 
    [Year], 
    [Month], 
    [Value], 
    [Cost], 
    Rank() OVER (PARTITION BY [Year], [Month] ORDER BY [DateTime] DESC) AS [Rank] 
    FROM [t1] 
) AS [sub] 
WHERE [Rank] = 1 
GROUP BY 
    [Year], 
    [Month], 
    [Value], 
    [Cost] 
ORDER BY 
    [Year] ASC, 
    [Month] ASC 

正如評論中所述,這可能仍然會爲一個月返回多個記錄。爲此在ORDER BY語句可以根據所需的功能進行擴展,:

Rank() OVER (PARTITION BY [Year], [Month] ORDER BY [DateTime] DESC, [Value] DESC, [Cost] ASC) AS [Rank] 

開關,因爲這個結果的[Value][Cost]ASC <>DESC順序會影響排名和。

+0

我正在嘗試這個腳本,結果邏輯是我所需要的,但是現在我可以看到,當我在[DateTime]中多出一個最大時間戳時,我得到了所有這些,當我只需要一個時。 我能做些什麼來解決這個問題? – BujinRikimaru

+0

我明白你的意思了。您必須擴展用於排名的ORDER BY。取決於什麼最適合你。我會在一會兒擴大我的答案。 – Jacco

+0

THX m8,但我得到了「V」標記給@bluefeet,因爲他的第一個例子給了我搜索的確切邏輯,並且演奏適合我。乾杯。 – BujinRikimaru

相關問題