我有一个表,我想根据优先级和日期明智获取记录,我通过此查询得到
SELECT *
FROM tbadv
WHERE advstrdat < CURDATE()
ORDER BY advenddat DESC,advpri=1 DESC,advpri=2 DESC,advpri=3 DESC,advpri=4 DESC,advpri=5 DESC
LIMIT 1
但是如果存在多个具有相同优先级的记录,那么我想从中随机记录.
告诉我在ORDER BY RAND()或使用JOIN之间我更喜欢哪个.
这些是我的表的列:
advid
advtit
advdes
advimg
advurl
advloc
advstrdat
advenddat
advpri
任何帮助,建议将非常感谢.
无论如何:
SELECT *
FROM tbadv
WHERE advstrdat < CURDATE()
ORDER BY advenddat DESC,advpri BETWEEN 1 AND 5 DESC,advpri DESC,RAND()
LIMIT 1
这将根据advenddat根据日期检索最新记录,无论优先级如何,即优先级较低的记录优先于较高优先级记录(因此,检查advenddat是日期而不是日期时间,或者,如果是,则用日期初始化.否则你很少有具有相同advenddat的记录,根据其他字段进行排序).
然后将选择优先级在1和5之间的那些记录.其中,优先级较高的人将优先考虑.
如果两个记录具有相同的advenddat且相同的advpri在1和5之间(例如,3),那么平局将随机打破.
出于性能原因,您需要按顺序在advstrdat,advenddat,advpri上设置覆盖索引:
CREATE UNIQUE INDEX tbadv_ndx ON tbadv ( advstrdat,advpri,advid );
如果表大,并且匹配了许多记录,则可以通过解耦记录选择(仅需要主键)和实际记录检索来实现最佳性能:
SELECT tbadv.*
FROM tbadv
JOIN (
SELECT advid
FROM tbadv
WHERE advstrdat < CURDATE()
ORDER BY advenddat DESC,RAND()
LIMIT 1 ) AS p
USING ( advid );
+----+-------------+------------+--------+---------------+-----------+---------+-------+-------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+-----------+---------+-------+-------+-----------------------------------------------------------+
| 1 | PRIMARY |
以上是一个大约13万行的样本表,非常不平衡(所有记录都有有效的curdate,都有有效的优先级等).然而,它在几毫秒内完成.
“无效”记录会快速过滤,因此性能等同于单个查询的性能,只有检索到的是advid:此处只有七个记录匹配:
+----+-------------+------------+--------+---------------+-----------+---------+-------+------+-----------------------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+--------+---------------+-----------+---------+-------+------+-----------------------------------------------------------+
| 1 | PRIMARY |
不同的顺序
如果你想优先考虑advenddat,即优先级为5的记录今天必须优先于优先级为4的记录,即使明年到期,你只需要反转advpri和advenddat的位置即可. :
ORDER BY advpri BETWEEN 1 AND 5 DESC,advenddat DESC,RAND()
现在优先级1-5先行,然后是优先级0,6,7,以及1-5之外的其他优先级;并且他们首先获得最高优先级(即5).如果两个记录具有相同的优先级,那么具有较长预期寿命的记录将首先出现.只有当预期寿命相同时,选择才是随机的. (您还必须在索引创建语句中交换字段位置).