2013-04-05 62 views
0

,所以我不能找到一個回答這個問題,我有以下查詢:亞目,其中字段0

SELECT * 
FROM bans 
WHERE 
    removed = 0 
AND 
    (
     (`time` + `length` - UNIX_TIMESTAMP()) > 0 
    OR 
     length = 0 
    ) 
ORDER BY length = 0,(`time` + `length` - UNIX_TIMESTAMP()) 

它得到他們根據從表和訂單的所有禁令時,他們會向被解除。但長度爲0的禁令是永久禁止的,它們應該位於列表的最底部。哪些已經有效。但我希望那些永久禁令被banid命令降序。目前它們並不是默認的順序升序。

如果我把ASC在它裏面空穴順序擰

數據庫:

CREATE TABLE IF NOT EXISTS `rp_bans` (
    `banid` int(11) NOT NULL AUTO_INCREMENT, 
    `steamid` text NOT NULL, 
    `name` text NOT NULL, 
    `adminid` text NOT NULL, 
    `aname` text NOT NULL, 
    `reason` text NOT NULL, 
    `time` int(11) NOT NULL, 
    `length` int(11) NOT NULL, 
    `removed` tinyint(1) NOT NULL, 
    PRIMARY KEY (`banid`) 
) 

示例數據:

id time length current time timeleft 
1 1365410228 0  1365411228 -1000 
2 1365410229 3600 1365411228 2601 
3 1365410230 0  1365411228 -998 
4 1365410231 84000 1365411228 83003 
5 1365410232 3600 1365411228 2604 
6 1365410233 0  1365411228 -995 
7 1365410234 800000 1365411228 799006 

預期結果:

id time length current time timeleft 
2 1365410229 3600 1365411228 2601 
5 1365410232 3600 1365411228 2604 
4 1365410231 84000 1365411228 83003 
7 1365410234 800000 1365411228 799006 
6 1365410233 0  1365411228 -995 
3 1365410230 0  1365411228 -998 
1 1365410228 0  1365411228 -1000 

所以如果長度不是0則按時間遞增順序(從時間+長度 - 當前時間計算)。當長度爲0,它需要通過ID下降的條目後面訂購,其中長度不爲0

+1

我們看一些樣本數據和期望的結果。 – Kermit 2013-04-05 14:16:01

+0

你的意思是*哪裏長度= 0下降*?降序在哪個屬性? – Oswald 2013-04-05 14:18:21

+0

希望這個清除它,長度= 0的所有行都需要使用banid或time來命令DESC(會給出相同的效果),並且它們需要在其他長度<> 0 – 2013-04-05 14:23:11

回答

1

你可以把它分解,並UNION他們:

(SELECT * FROM rp_bans WHERE length > 0 ORDER BY id ASC LIMIT 10) 
UNION 
(SELECT * FROM rp_bans WHERE length = 0 ORDER BY id DESC LIMIT 10) 

你必須LIMIT他們。從docs

然而,使用ORDER BY的個人SELECT語句並不意味着要在該行出現在最終的結果,因爲UNION默認情況下會產生一組無序行的順序。因此,在此上下文中使用ORDER BY通常與LIMIT結合使用,以便它用於確定要爲SELECT檢索的所選行的子集,即使它不一定會影響SELECT中這些行的順序最終UNION結果。

我發現採取LIMIT比結果更好。

+0

我試圖弄清楚如何去做,並附帶一個例子。 – 2013-04-05 14:24:42

+0

不回答問題 – 2013-04-05 14:25:31

+0

如果長度爲0,我的回答順序按長度和banid遞減。測試它並運行。 – 2013-04-05 14:29:23

1

嘗試這樣

ORDER BY IF(length=0, length DESC ,(`time` + `length` - UNIX_TIMESTAMP()) DESC) 

編輯:

ORDER BY 
CASE WHEN length=0 = 0 THEN length END DESC, 
(`time` + `length` - UNIX_TIMESTAMP()) DESC 

編輯:

ORDER BY 
CASE WHEN length != 0 THEN length END ASC, 
CASE WHEN length =0 then time END DESC 

DEMO

+0

MySQL似乎不接受'IF'中的'DESC'。 – 2013-04-05 14:28:33

+0

刪除多餘的空格。 – fedorqui 2013-04-05 14:31:12

+0

編輯我的答案 – 2013-04-05 14:40:31

0

更改ORDER BY

ORDER BY length = 0, banid DESC 

請注意,您的查詢將永遠做一個全表掃描,由於OR條款。

這個查詢將有更好的表現:

SELECT * 
    FROM rp_bans 
    WHERE 
     removed = 0 
    AND 
     length = 0 
UNION ALL 
    SELECT * 
    FROM rp_bans 
    WHERE 
     removed = 0 
    AND 
     length > 0 AND (time + length) > UNIX_TIMESTAMP() 
ORDER BY length = 0, banid DESC 

如果您添加以下指標:

ALTER TABLE rp_bans ADD INDEX removed_length_time (removed, length, time); 

的工作的例子是在http://sqlfiddle.com/#!2/45fa6/2/0

+0

試過它沒有給出我正在尋找的結果,我更新了最初的問題,所以我希望它澄清更好 – 2013-04-08 08:05:55