2015-05-21 57 views
0

我試圖根據時間戳數據類型的列字段對SQL元組進行排序。在My Sql中的timestamp列進行排序 - not varchar列

在表中的數據是這樣的:

id  attribute value  updated 
------------------------------------------------- 
'3449' 'HEIGHT' '12'  '2013-11-30 03:20:25' 
'3449' 'HEIGHT' '15'  '2013-12-10 03:20:25' 


select *, count(1) as cnt from attribute_table 
where id ='3449' 
group by id,attribute having cnt > 1 
ORDER BY updated; 

輸出是一些像這樣的事情,無論我在順序的末尾BY語句添加ASC/DESC參數的事實,結果保持不變。

id  attribute value  updated 
------------------------------------------------- 
'3449' 'HEIGHT' '12'  '2013-11-30 03:20:25' 

更新的列的數據類型爲timestamp,而不是varchar其他類似的問題已經對SO。

如何按更新的列進行排序?

+0

根據您的分組有,無論如何,你只會從樣本數據中獲得一行。排序不會有幫助,因爲您沒有在更新的列上使用聚合函數,mysql會爲您選擇值 –

+0

是的,但我想獲取最新的行。 – LearningToDesign

+0

每組最新一行還是最新一行? –

回答

-1

您使用的骨料,group by在mysql中需要被分組到一行的所有行的第一行。

由於有2行滿足您的組條件,使得所述第一(即,頂部)行被拾取的結果集。

你,不知何故,需要把它放在最上面。一個可能的轉身,是結果第一組進行排序,把排在最前面,並通過執行組。

select *, count(1) as cnt from (select * from attribute_table order by 
updated desc) as alias 
where id ='3449' 
group by id,attribute having cnt > 1 
ORDER BY updated; 
+0

它給錯誤代碼:1248.每個派生表必須有自己的別名 – LearningToDesign

+0

現在嘗試@LearningToDesign剛剛編輯它..因爲我不在mysql客戶端執行它,我忘了添加派生表的別名。 –

+0

謝謝丹尼爾。現在正在工作。 – LearningToDesign

1

這種類型的問題的一般解決方案是一個兩步過程。首先,找到最新的行每個ID:

select id, attribute, max(updated) last_updated 
    from <your_table> 
    group by id, attribute 

接下來,我們需要加入這一結果,回到談判桌再次得到數據的其餘部分。

select t.* 
    from <your_table> t 
    inner join (
     select id, attribute, max(updated) last_updated 
     from <your_table> 
     group by id, attribute 
    ) q 
    on t.id = q.id 
     and t.updated = q.last_updated 
     and t.attribute = q.attribute 

而這應該給你你想要的結果。

quick demo here

的原因,你的嘗試不起作用,下降到是,MySQL句柄分組對未在group by子句中使用,或在聚合函數中使用的字段的方式。

它實際上是一個方便的是,MySQL可以讓你在這個問題選擇字段可言,大部分(如果不是全部)其他RDBMS會如果您嘗試拋出一個錯誤,並做到這一點。

12.16.3 MySQL Handling of GROUP BY會給你辦下來,但重要的部分是這樣的:

您可以使用此功能,避免不必要的 列排序和分組,以獲得更好的性能。但是,這主要是當 GROUP BY中每個未組合的每個非聚合列中的所有值對於每個組都相同時有用 。服務器可以自由選擇每個組中的任何值 ,因此除非它們相同,否則所選的值爲 是不確定的。

而這就是爲什麼它沒有選擇你想要的日期或價值。

0

您可以使用變量每id確定排名最高的紀錄,attribute

SELECT id, attribute, value, updated 
FROM (
SELECT value, updated, 
     @row_number:= CASE WHEN @id = id AND @attr = attribute THEN @row_number+1 
          ELSE 1 
        END AS rn, 
     @id:=id AS id, 
     @attr:=attribute AS attribute 
FROM attribute_table, (SELECT @row_number:=0, @id:=0, @attr:='') AS vars 
ORDER BY id, attribute, updated DESC) t 
WHERE t.rn =1 

rn = 1謂詞將選擇具有每id最近updated值,attribute這些記錄。

SQL Fiddle Demo

編輯:

通過@pala_該考慮到的意見是查詢應該如何看起來像:

SELECT id, attribute, value, updated 
FROM (
SELECT id, attribute, value, updated, 
     if (@id = id AND @attr = attribute, 
      if (@id:=id, 
       if (@attr:=attribute, @row_number:= @row_number + 1, @row_number:= @row_number + 1), 
       if (@attr:=attribute, @row_number:= @row_number + 1, @row_number:= @row_number + 1) 
      ), 
      if (@id:=id, 
       if (@attr:=attribute, @row_number:= 1, @row_number:= 1), 
       if (@attr:=attribute, @row_number:= 1, @row_number:= 1) 
      ) 
     ) AS rn 
FROM attribute_table, (SELECT @row_number:=0, @id:='', @attr:='') AS vars 
ORDER BY id, attribute, updated DESC) t 
WHERE t.rn = 1 

SQL Fiddle Demo

+0

這是一個不必要的複雜(並可能被破壞)的方法來完成一件簡單的事情。您無法控制mysql在select語句中評估字段的順序,所以雖然偶爾可能會發現變量具有您期望的值,但無法保證。 –

+0

@pala_變量正在應用於*有序集*。看看這個:http://www.mysqltutorial.org/mysql-row_number/ –

+0

我不需要。您的id和attr分配發生在case語句之外,可以在您的case語句之前或之後進行評估 –