2017-03-02 39 views
1

我想顯示前兩個頂部票選文章然後其他人通過編號的順序排列mysql命令由前兩名再ID

這是表

+----+-------+--------------+--------+ 
| Id | Name | Post   | Votes | 
+====+=======+==============+========+ 
| 1 | John | John's msg | -6  | 
| 2 |Joseph |Joseph's msg | 8  | 
| 3 | Ivan | Ivan's msg | 3  | 
| 4 |Natalie|Natalie's msg | 10  | 
+----+-------+--------------+--------+ 

後查詢的結果應該是:

+----+-------+--------------+--------+ 
    | Id | Name | Post   | Votes | 
    +====+=======+==============+========+ 
    | 4 |Natalie|Natalie's msg | 10  | 
    | 2 |Joseph |Joseph's msg | 8  | 
----------------------------------------------- 
    | 1 | John | John's msg | -6  | 
    | 3 | Ivan | Ivan's msg | 3  | 
    +----+-------+--------------+--------+ 

我有1個解決方案,但我覺得有更好更快的方法來做到這一點。 我跑2個查詢,一個到達頂部2,然後第二個讓別人:

SELECT * FROM table order by Votes desc LIMIT 2 

SELECT * FROM table order by Id desc 

然後在PHP我要確保我表明1日的查詢,因爲它是和上顯示2號查詢我刪除條目的那在第一個查詢中,所以它們不會加倍。 可這在單一的查詢進行選擇前兩個頂部投票,那麼其他人呢?

回答

2

你將不得不使用子查詢或工會 - 這意味着你有一個外部查詢,這裏麪包含多個查詢。我只想從第一個查詢檢索ID和(...)標準添加一個ID沒有第二個查詢的WHERE子句 - 從而過濾掉第一個查詢檢索到的帖子:

SELECT * FROM table WHERE Id NOT IN (...) ORDER BY Id DESC 

隨着union查詢看起來像如下:

(SELECT table.*, 1 as o FROM table order by Votes desc LIMIT 2) 
UNION 
(SELECT table.*, 0 FROM table 
    WHERE Id NOT IN (SELECT Id FROM table order by Votes desc LIMIT 2)) 
ORDER BY o DESC, if(o=1,Votes,Id) DESC 

正如你所看到的,它包裝3個查詢轉換之一,擁有更復雜的排序中,因爲union的檢索記錄的順序不能保證。

兩個簡單的查詢,似乎對我很重要更有效的在這種特殊情況下。

+0

我認爲MySQL不支持子查詢有限制,但你可以使用一個連接,而不是 – fthiella

+0

@fthiella請檢查出工會的鏈接。它說,否則:) – Shadow

+0

是,這個問題是不是聯合查詢,其中支持的限制,但對'NOT IN(選擇... LIMIT 2)'它不 – fthiella

1

有可能是寫在你想要的順序返回行的查詢不同的方式。我的解決辦法是這樣的:

select 
    table.* 
from 
    table left join (select id from table order by votes desc limit 2) l 
    on table.id = l.id 
order by 
    case when l.id is not null then votes end desc, 
    tp.id 

子查詢將返回前兩個ID的票降序排列,連接每當行前兩個否則l.id將是無效的,而不是一個會成功。

按順序按票數排序desc只要行是第一個或第二個(= l.id不爲空),當l.id爲null時,它將把行放在最下面並按順序排列代替。