2012-01-25 70 views
7

我試圖從MySQL數據庫中獲取許多行,並在發佈日將它們分組。MySQL GROUP BY UNIX TIMESTAMP

最終的結果,我想下面..

週一 -Article 1 -Article 2 -Article 3

週二 -Article 1 -Article 2

週三 - 第1條 -Article 2 -Article 3 -Article 4

等等,我不確定這是否可以在沒有PHP做額外工作的情況下在MySQL中完成。

這是我迄今爲止的查詢,但似乎沒有按天分組。

SELECT 
cms_news.news_id, 
cms_news.news_title, 
cms_news.news_date, 
cms_news.news_category, 
cms_news.news_source, 
cms_news.news_type, 
cms_news.news_content 
FROM 
cms_news cms_news, 
GROUP BY 
DAYOFMONTH(FROM_UNIXTIME(cms_news.news_date)) 
ORDER BY 
cms_news.news_date DESC 

謝謝。

+0

刪除GROUP BY之前的逗號和查詢將工作。 –

+0

此查詢將只給出每天匹配的第一行。這可以通過'GROUP_CONCAT()'來實現,但結果不容易重複使用。爲什麼你不能使用PHP? –

+1

你應該通過PHP來完成。大多數僅MySQL解決方案將使用「GROUP_CONCAT()」函數,該函數將列的大小限制爲1KB。如果你有幾十條這樣的查詢不會給你一個完整的圖片。 –

回答

1

使用查詢像這樣得到正確的順序中的數據:

SELECT 
DAYNAME(FROM_UNIXTIME(cms_news.news_date)) AS DayName, 
cms_news.* 
FROM cms_news 
ORDER BY DAYOFWEEK(FROM_UNIXTIME(cms_news.news_date)), cms_news.news_date 

DAYOFWEEK返回之間的數字。 1和7(1 =星期日),所以你的結果將在週日到週六進行排序。 DAYNAME返回一天中的文字名稱(星期日,星期一,...)。然後,您可以使用PHP對數據進行分組和顯示:

$DayName = ""; 
while($row = mysql_fetch_assoc($query)) { 
    if ($DayName != $row['DayName']) { 
     $DayName = $row['DayName']; 
     echo "<br>\n" . $DayName . ": "; 
    } 
    echo $row['news_title'] . ", "; 
} 
1

我想你可以嘗試GROUP_CONCAT(cms_news.news_title SEPARATOR' - ')。更多信息請訪問:http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat

實際解決問題的一些未經檢驗的查詢:

SELECT 
    cms_news.news_id, 
    CONCAT(
    DAYNAME(FROM_UNIXTIME(cms_news.news_date)), 
    ' - ', 
    GROUP_CONCAT(cms_news.news_title SEPARATOR ' - ') 
) as result, 
cms_news.news_date 
FROM 
cms_news cms_news 
GROUP BY 
DAYOFMONTH(FROM_UNIXTIME(cms_news.news_date)) 
ORDER BY 
cms_news.news_date DESC 
1

不幸的是MySQL的做這樣的事情veeeery緩慢的,因爲你不能爲這個排序創建索引。 我建議你使用Postgres ;-) 但在你的情況下,你應該將結果分組到PHP端,但是避免使用大量的數據,PHP會消耗太多的內存來存儲它。

+1

不幸的是MySQL做這樣的事情。 –

+0

但非常慢!我剛剛在桌面上測試了小於3KK的行,響應時間爲2分22.64秒,儘管數據庫位於內存中! – n0nSmoker

+0

確實!慢,但確實如此。無論如何,我確信他不需要處理所有的數據,而且這種查詢可能會被緩存。最後,這可能是他的問題的解決方案。 –

2

該查詢與GROUP_CONCAT()

SELECT 
    news_id 
, news_date AS "date" 
, GROUP_CONCAT(news_title) AS "articles" 
FROM cms_news 
GROUP BY news_date 
ORDER BY news_date DESC 
; 

但不容易使用後limited in size(1kB的默認值)。

這個簡單的查詢

SELECT 
    news_id 
, news_date AS "date" 
, news_title AS "article" 
FROM cms_news 
ORDER BY news_date DESC 
; 

你可以很容易地用PHP重新編制。

// Day Index 
$data = array(); 
while ($row = mysql_fetch_assoc($result)) { 
    $data[$row['date']][] = $row; 
} 
// Display 
foreach ($data as $date => $row) { 
    echo ($date.' : '.implode(' - ', $row['article'])); 
} 
4

你上面的查詢不工作,除了,當你GROUP BY一列,你必須以某種方式聚集所有其他人。

例如,GROUP BY Day每天返回一條記錄。如果每天有多個記錄輸入,並且您要求他們的id,title,category等,那麼MySQL如何知道將向您顯示哪個倍數,因爲它只顯示一行? (它通常顯示每天的第一排,因爲它們出現在"SELECT * FROM mytable"中,但不應該依賴於此)。

解決方法是,您可以以某種方式將所有這些單獨的屬性(如id)合併到一個組中的一個字符串中。你可以使用GROUP_CONCAT作爲@narcisradu的建議。

SELECT 
GROUP_CONCAT(cms_news.news_id), 
GROUP_CONCAT(cms_news.news_title), 
DAYOFMONTH(FROM_UNIXTIME(cms_news.news_date)) as Day, 
GROUP_CONCAT(cms_news.news_category), 
GROUP_CONCAT(cms_news.news_source), 
GROUP_CONCAT(cms_news.news_type), 
GROUP_CONCAT(cms_news.news_content) 
FROM 
cms_news cms_news, 
GROUP BY 
DAYOFMONTH(FROM_UNIXTIME(cms_news.news_date)) 
ORDER BY 
cms_news.news_date DESC 

這會給你例如: -

1,4  Story 1 Title, Story 2 Title  <Day1>  Funny,Sad .... 

即每日的ID,標題,類別,來源,類型和內容將變成一個以逗號分隔的字符串。

但是,它似乎不適合你的目的(有一個字符串與當天的所有文章的內容似乎無意義)。

我想你應該讓你的查詢:

SELECT 
cms_news.news_id, 
cms_news.news_title, 
DAYNAME(FROM_UNIXTIME(cms_news.news_date)) AS Day, 
cms_news.news_category, 
cms_news.news_source, 
cms_news.news_type, 
cms_news.news_content 
FROM 
cms_news cms_news, 
ORDER BY news_date DESC 

(請注意,我改變了你的DAYOFMONTHDAYOFWEEK,因爲它似乎更符合你原來的問題。)

的變化是,有沒有分組 - 只是按日期排序。

由於您的輸出按日期排序,日期名稱也將按順序排列。

你可以做這樣的事情在你的PHP則:

$prevday=''; 
while($row = mysql_fetch_array($res)) { 
    if ($row['Day'] != $prevday) { 
     // day has changed! 
     // make a new row. e.g: 
     echo "<br/> \n" . $row['Day']; 
    } 
    // now just list your article name 
    echo " - " . $row['news_title']; 
    $prevday = $row['Day']; 
}