2011-10-07 72 views
0

我有一個大的查詢,最終返回並訂購了我想要的任何東西。MySQL LIMIT和OFFSET弄亂我的結果順序

我堅持分頁在我的項目,但現在LIMIT和OFFSET是在查詢的結果進行排序不同。 任何想法?

增加了更多的信息 -

我的表有幾分這樣的:

ANIMAL      FOOD 
AID AnimalName    FID FoodName  BuyOn   AID 
------------------   ------------------------------------------ 
1  Dog     1  DogBix   2011-11-27  1   
2  Cat     2  Tuna   2011-11-11  2 
3  Rabbit    3  Bones   2012-06-08  1 
4  Bird     4  CatBix   2010-06-04  2 
           5  Bird Seed  2011-12-12  4 
           6  Carrots  2011-05-04  3 
           7  Pedigree Chum 2011-02-08  1 
           8  Rabbit Mix  2011-09-02  3 

而且我想在下面這個命令的輸出:

AnimalName FoodName  BuyOn 
---------------------------------------- 
Cat   Tuna   2011-11-11 
Cat   CatBix   2010-06-04 

Dog   DogBix   2011-11-27 
Dog   Bones   2012-06-08 
Dog   Pedigree Chum 2011-02-08 

Bird   Bird Seed  2011-12-12 

Rabbit  Rabbit Mix  2011-09-02 
Rabbit  Carrots  2011-05-04 

那麼有序,按照與現在最接近的未來日期按動物分組。 動物的相關日期按最接近現在升序的日期排序,然後是最接近現在降序的過去日期。

查詢我有是這樣的:

$offset = ~whatever page I'm on * LIMIT~ 

$Query = " 
    SELECT * 
    FROM animal AS a 
    INNER JOIN food AS f ON a.aid = f.fid 
    INNER JOIN 
    (
    SELECT f2.aid, 
    MIN(IF(DATEDIFF(f2.buyOn, CURDATE()) >= 0, DATEDIFF(f2.buyOn, CURDATE()), 1000000)) AS dateSortFuture, 
    MAX(IF(DATEDIFF(f2.buyOn, CURDATE()) < 0, DATEDIFF(f2.buyOn, CURDATE()), -1000000)) AS dateSortPast 
    FROM food AS f2 
    GROUP BY f2.aid 
LIMIT 5 
OFFSET ".$offset." 
) 
    AS f3 ON f3.aid = a.aid 
    ORDER BY f3.dateSortFuture ASC, 
    f3.dateSortPast DESC, 
    IF(f.buyOn >= CURDATE(), 0, 1) ASC, 
    ABS(DATEDIFF(f.buyOn, CURDATE())) ASC, animalName;"; 

隨着LIMIT和OFFSET去除它的作品,因爲我想要的。

可能的解決方案?:

$Query = " 
    SELECT * 
    FROM animal AS a 
    INNER JOIN food AS f ON a.aid = f.fid 
    INNER JOIN 
    (
    SELECT f2.aid, 
    MIN(IF(DATEDIFF(f2.buyOn, CURDATE()) >= 0, DATEDIFF(f2.buyOn, CURDATE()), 1000000)) AS dateSortFuture, 
    MAX(IF(DATEDIFF(f2.buyOn, CURDATE()) < 0, DATEDIFF(f2.buyOn, CURDATE()), -1000000)) AS dateSortPast 
    FROM food AS f2 
    GROUP BY f2.aid 
    ORDER BY f3.dateSortFuture ASC, 
    f3.dateSortPast DESC, 
    IF(f.buyOn >= CURDATE(), 0, 1) ASC, 
    ABS(DATEDIFF(f.buyOn, CURDATE())) ASC, animalName; 
LIMIT 5 
OFFSET ".$offset." 
) 
    AS f3 ON f3.aid = a.aid 
    ORDER BY f3.dateSortFuture ASC, 
    f3.dateSortPast DESC, 
    IF(f.buyOn >= CURDATE(), 0, 1) ASC, 
    ABS(DATEDIFF(f.buyOn, CURDATE())) ASC, animalName; 
    "; 
+2

請附上您的查詢,預期產出和你的問題實際輸出。 – JohnFx

回答

1

LIMITOFFSET通常不是你想要的,除非有在同一查詢ORDER BY。在您的示例代碼中,LIMIT位於子查詢中,並且該子查詢中的記錄是無序的。所以基本上,你從f3得到一個隨機的5行。

不幸的是,目前最好的方法,我知道的處理,這是與窗口,它的MySQL還不支持(據我所知)。你能砍了一個片段類似像

(SELECT f9.*, (SELECT COUNT(*) FROM mytable as f99 
       WHERE f99.sortkey <= f9.sortkey) 
       AS rank 
FROM mytable AS f9) AS kludge 

,然後有這樣的代碼

SELECT /* lots */ FROM 
mytable join myothertable ON /* blah */ 
JOIN /* copy above fragment */ 
ON kludge.id = mytable.id AND rank<=5; 
+0

這個查詢越來越糾結,因爲我繼續.. 我明白你的意思是需要在有限的子查詢記錄之前進行訂購,現在看起來很明顯! 我會再看一些,謝謝。 – penpen

+0

我現在正在進行求職面試,這個查詢是「Hunh?你爲什麼喜歡Postgres到MySQL?」的答案。 –

+0

那麼MySQL是我所知道的,但是開始想到擴展我的知識並從看看MariaDB開始。你會推薦Postgres嗎? 編輯在與好像我現在擁有的數據工作的解決方案,但因爲擔心某些領域它隨機不此起彼伏/效能問題現在 – penpen