php – 根据priorty随机获取记录

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

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

  1. SELECT *
  2. FROM tbadv
  3. WHERE advstrdat < CURDATE()
  4. ORDER BY advenddat DESC,advpri=1 DESC,advpri=2 DESC,advpri=3 DESC,advpri=4 DESC,advpri=5 DESC
  5. LIMIT 1

但是如果存在多个具有相同优先级的记录,那么我想从中随机记录.

告诉我在ORDER BY RAND()或使用JOIN之间我更喜欢哪个.

这些是我的表的列:

  1. advid
  2. advtit
  3. advdes
  4. advimg
  5. advurl
  6. advloc
  7. advstrdat
  8. advenddat
  9. advpri

任何帮助,建议将非常感谢.

最佳答案
你不知道如何解决关系.

无论如何:

  1. SELECT *
  2. FROM tbadv
  3. WHERE advstrdat < CURDATE()
  4. ORDER BY advenddat DESC,advpri BETWEEN 1 AND 5 DESC,advpri DESC,RAND()
  5. LIMIT 1

这将根据advenddat根据日期检索最新记录,无论优先级如何,即优先级较低的记录优先于较高优先级记录(因此,检查advenddat是日期而不是日期时间,或者,如果是,则用日期初始化.否则你很少有具有相同advenddat的记录,根据其他字段进行排序).

然后将选择优先级在1和5之间的那些记录.其中,优先级较高的人将优先考虑.

如果两个记录具有相同的advenddat且相同的advpri在1和5之间(例如,3),那么平局将随机打破.

出于性能原因,您需要按顺序在advstrdat,advenddat,advpri上设置覆盖索引:

  1. CREATE UNIQUE INDEX tbadv_ndx ON tbadv ( advstrdat,advpri,advid );

如果表大,并且匹配了许多记录,则可以通过解耦记录选择(仅需要主键)和实际记录检索来实现最佳性能

  1. SELECT tbadv.*
  2. FROM tbadv
  3. JOIN (
  4. SELECT advid
  5. FROM tbadv
  6. WHERE advstrdat < CURDATE()
  7. ORDER BY advenddat DESC,RAND()
  8. LIMIT 1 ) AS p
  9. USING ( advid );
  10. +----+-------------+------------+--------+---------------+-----------+---------+-------+-------+-----------------------------------------------------------+
  11. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  12. +----+-------------+------------+--------+---------------+-----------+---------+-------+-------+-----------------------------------------------------------+
  13. | 1 | PRIMARY |

以上是一个大约13万行的样本表,非常不平衡(所有记录都有有效的curdate,都有有效的优先级等).然而,它在几毫秒内完成.

“无效”记录会快速过滤,因此性能等同于单个查询性能,只有检索到的是advid:此处只有七个记录匹配:

  1. +----+-------------+------------+--------+---------------+-----------+---------+-------+------+-----------------------------------------------------------+
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  3. +----+-------------+------------+--------+---------------+-----------+---------+-------+------+-----------------------------------------------------------+
  4. | 1 | PRIMARY |

不同的顺序

如果你想优先考虑advenddat,即优先级为5的记录今天必须优先于优先级为4的记录,即使明年到期,你只需要反转advpri和advenddat的位置即可. :

  1. ORDER BY advpri BETWEEN 1 AND 5 DESC,advenddat DESC,RAND()

现在优先级1-5先行,然后是优先级0,6,7,以及1-5之外的其他优先级;并且他们首先获得最高优先级(即5).如果两个记录具有相同的优先级,那么具有较长预期寿命的记录将首先出现.只有当预期寿命相同时,选择才是随机的. (您还必须在索引创建语句中交换字段位置).

猜你在找的MySQL相关文章