我有一个数据库表,它有两个字段,日期和名称。
我希望我的查询先按最新日期前20,然后查询的其余部分按名称按字母顺序提取其他元素。
这样,前20个最新产品将首先显示,其余的将按名称排序。
答案 0 :(得分:4)
这有点难看,但你可以在一个查询中完成:
SELECT name,
`date`
FROM ( SELECT @rank := @rank + 1 AS rank,
name,
`date`
FROM (SELECT @rank := 0) dummy
JOIN products
ORDER BY `date` DESC, name) dateranked
ORDER BY IF(rank <= 20, rank, 21), name;
最里面的查询dummy
初始化我们的@rank
变量。下一个派生表dateranked
按新近度排列所有行(按name
打破关联)。然后,最外面的查询只是按计算的rank
重新排序行,将排名大于20的排名排在第21位,然后排在name
之后。
UPDATE:此查询版本更紧凑,将条件排名逻辑放在最外层的ORDER BY中,使用IF()而不是CASE / END。
答案 1 :(得分:0)
我担心必须通过向表中添加特殊列或创建临时表TPup来完成此操作。如果你让我知道你是否对这些选项感兴趣,我会告诉你更多。
以下两个查询选项可能是可能的,但我的MySQL版本告诉我LIMIT在子查询中不可用。
SELECT `date`, `name` from `table` ORDER BY `date` LIMIT 0, 20;
SELECT `date`, `name` from `table` WHERE `id` NOT IN (SELECT `id` from `table` ORDER BY `date` LIMIT 0, 20) ORDER BY `name`;
答案 2 :(得分:-1)
使用sql UNION运算符组合两个SELECT查询的结果。
根据MySQL docs:
对单个SELECT语句使用ORDER BY意味着什么 关于行在最终结果中出现的顺序,因为 UNION默认生成一组无序行。
...
使用ORDER BY或LIMIT子句对整个UNION进行排序或限制 结果,括起单个SELECT语句并放置 最后一个之后的ORDER BY或LIMIT。以下示例使用两个子句:
(SELECT a FROM t1 WHERE a=10 AND B=1)
UNION
(SELECT a FROM t2 WHERE a=11 AND B=2)
ORDER BY a LIMIT 10;
击> <击> 击><击> 撞击>
修改强> 我错过了解释OP需要按日期排序一组结果而按字母顺序排序结果的另一组的部分。我认为您需要为排序目的创建一个临时字段。而SQL查询将与此类似。
(SELECT *, 'firstset' as set_id FROM t1 ORDER BY date LIMIT 0, 20)
UNION
(SELECT *, 'secondset' as set_id FROM t1 ORDER BY date LIMIT 20, 18446744073709551615)
ORDER BY
CASE
WHEN set_id='firstset' THEN date
WHEN set_id='secondset' THEN name
END DESC ;