我有一个大查询,最终返回并订购我想要的所有内容。
我在我的项目中坚持分页,但是现在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;
";
答案 0 :(得分:1)
LIMIT
,否则 OFFSET
和ORDER BY
通常不是您想要的。在示例代码中,LIMIT
位于子查询中,并且该子查询中的记录是无序的。所以基本上,你从f3
得到一个随机的5行。
不幸的是,到目前为止,我所知道的处理这个的最好方法是使用窗口,MySQL还不支持(AFAIK)。你可以用类似
的片段来破解类似的东西(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;