2012-01-06 45 views
1

我有一個數據庫表,有兩個字段,日期和名稱。MySQL查詢與前20個項目由一個字段排序和休息按名稱排序ASC

我想讓我的查詢先將最新的日期拉到前20,然後查詢的其餘部分按字母順序將其他元素拉出。

這樣,前20名最新的產品將首先顯示,然後剩下的將按名稱排序。

+1

我很抱歉沒有發佈我曾經嘗試過的,在這一點上,我正在寫一些僞netsted查詢,哦,上帝,我在這個網站上顯示我的n00bness ..... – TPup 2012-01-06 01:30:43

+0

不確定關於MySQL,但Oracle允許請按照 – Randy 2012-01-06 01:57:48

+0

的順序排列案例陳述您如何要求最近的記錄在配合情況下訂購?如果50或100或所有記錄具有相同的最近日期,會發生什麼情況? – pilcrow 2012-01-06 02:24:40

回答

4

這是一個有點難看,但你可以在一個查詢做到這一點:

SELECT name, 
     `date` 
    FROM ( SELECT @rank := @rank + 1 AS rank, 
       name, 
       `date` 
      FROM (SELECT @rank := 0) dummy 
      JOIN products 
     ORDER BY `date` DESC, name) dateranked 
ORDER BY IF(rank <= 20, rank, 21), name; 

的最內層查詢,dummy,我們初始化變量@rank。下一個派生表dateranked按近因次排列所有行(通過name打斷關係)。最外面的查詢然後簡單地通過我們的計算的rank重新排序行,將排名大於20的排名作爲排名#21,然後排列爲name

UPDATE:該查詢版本更緊湊,將條件排名邏輯放在最外面的ORDER BY中,使用IF()而不是CASE/END。

+0

這是一個非常好的答案。如果它真的有效,我希望提問者將其標記爲已接受的答案。 – 2012-01-06 05:57:26

+0

謝謝,@TomHaws。我更新了一個更清晰和等效的查詢版本。 – pilcrow 2012-01-06 15:47:36

+0

我真的很喜歡你實現IF而不是CASE。現在我需要研究你的查詢,因爲它使用了我不知道的一些東西! – 2012-01-06 15:55:49

0

恐怕這需要通過在表格中添加一個特殊的列或創建一個臨時表TPup來完成。如果你讓我知道你是否對這些選項感興趣,我會告訴你更多。

像下面這樣的兩個查詢選項可能是可能的,但是我的MySQL版本告訴我LIMIT在子查詢中不可用。

SELECT `date`, `name` from `table` ORDER BY `date` LIMIT 0, 20; 
SELECT `date`, `name` from `table` WHERE `id` NOT IN (SELECT `id` from `table` ORDER BY `date` LIMIT 0, 20) ORDER BY `name`; 
-1

使用SQL UNION操作員兩個SELECT查詢結果相結合。

根據MySQL docs

使用ORDER BY的個人SELECT語句意味着什麼 有關該行出現在最終的結果,因爲 UNION默認情況下會產生一組無序行的順序。

...

要使用ORDER BY或LIMIT子句來進行排序或限制整個UNION 結果,圓括號個人SELECT語句,並放置 ORDER BY或LIMIT最後一個之後。下面的示例使用這兩種條款:

(SELECT a FROM t1 WHERE a=10 AND B=1) 
UNION 
(SELECT a FROM t2 WHERE a=11 AND B=2) 
ORDER BY a LIMIT 10; 

編輯: 我錯過了解釋OP需要的日期和一組結果的排序的部分按字母順序排列其他一組結果。我認爲你需要爲排序目的創建一個臨時字段。和SQL查詢將是類似的東西。

(SELECT *, 'firstset' as set_id FROM t1 ORDER BY date LIMIT 0, 20) 
UNION 
(SELECT *, 'secondset' as set_id FROM t1 ORDER BY date LIMIT 20, 18446744073709551615) 
ORDER BY 
CASE 
    WHEN set_id='firstset' THEN date 
    WHEN set_id='secondset' THEN name 
END DESC ; 
+0

當您分別對每個子集進行排序時 - 有機會通過索引提高性能。當您排序整個查詢 - 有沒有這樣的機會,所有的數據在內存(不好)進行排序 – zerkms 2012-01-06 03:42:38