php – 根据priorty随机获取记录

前端之家收集整理的这篇文章主要介绍了php – 根据priorty随机获取记录前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我有一个表,我想根据优先级和日期明智获取记录,我通过此查询得到

  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).如果两个记录具有相同的优先级,那么具有较长预期寿命的记录将首先出现.只有当预期寿命相同时,选择才是随机的. (您还必须在索引创建语句中交换字段位置).

猜你在找的MySQL相关文章