2011-12-03 24 views
6

比方說,我想要從一個叫messages表100分的記錄,我想獲得它們的方式如下:是否有可能在SQL中的SELECT中合併?

1st message 
100th message 
2nd message 
99th message 
3rd message 
98th message 
(...) 

有沒有辦法做到這一點有效?什麼是適當的查詢? 或者我應該查詢選擇前50,查詢選擇最後50,然後合併結果?

+0

這是一個情況下,我可能會做兩個查詢,並在應用程序代碼合併。通過創建行號和使用非常聰明的條件'ORDER BY',可以在一個查詢中完成,但在應用程序代碼中執行起來要容易得多。 –

+0

是的,我想也是一樣......可能用兩個不同的查詢做它更容易/更有效率,並在代碼中合併它們的結果 – federicot

+0

我一定會等待看看這裏的某個人是否能夠生成一個巧妙的解決方案。這裏有一些相當聰明的人。 –

回答

2

嘗試,如果你的ID是數字的序列:

首先

SET @half = (SELECT MAX(id) FROM messages)/2; 

然後

SELECT * FROM `messages` ORDER BY (IF(id<@half,@half*2-id,id-1)) DESC,id ASC; 
+0

爲100的限制,在查詢結束時的極限「極限100」... –

+0

最後的「ASC」應該是「DESC」。除此之外,這是完美的,它是所有這些的最簡單的解決方案。謝謝! – federicot

+0

有點太遲不能問......但是如果不是通過'id'命令,我按'timestamp'命令(使用'UNIX_TIMESTAMP(timestamp)')? – federicot

0

的一點是要創建兩個虛擬列 「serie_order」(變體)和「系列「(常量),你將使用你的兩部分數據(你將不得不將數據分成兩部分)。

SELECT * FROM (
    SELECT 1 as serie, message_id AS serie_order , * FROM 
    (SELECT message_id FROM messages) as part_up 
UNION 
    SELECT 2 as serie, 101-message_id as serie_order, * FROM 
    (SELECT message_id FROM messages) as part_down 
) AS world 

ORDER BY serie_order ASC, serie ASC 
LIMIT 100 
+0

可悲的是,MySQL缺少'generate_series()'函數。 – pilcrow

+0

這只是作爲虛擬數據使用,我使用操作「消息」表編輯 – 131

+0

這是正確的想法,但不完全正確。在SELECT中需要首先出現「*」,否則就是語法錯誤。另外,如果「消息」有200行?順便說一句,您不需要最內層的派生表,因爲您可以簡單地使用'SELECT 1 AS serie,message_id AS serie_order,message_id FROM messages'。 – pilcrow

0
set @rank:=0; 

select id from 
(select id, @rank:=(coalesce(@rank, 0)+1) as new_order 
from a_table 
order by some_column limit 100) as ordering 
order by if (new_order<=50, new_order-1, abs(100-new_order)) asc; 
+1

差不多!在你的ORDER BY子句中,「new_order」1和「new_order」100都變爲0,而2和99變成1等。MySQL如何知道首先放哪個記錄?您需要第二個ORDER BY條件,如[本答案](http://stackoverflow.com/a/8371930/132382),以保證正確的輸出。 – pilcrow

相關問題