2

我有一排要在摄影网站主页上展示的照片。摄影师倾向于一次上传几十张照片,这意味着选择最佳上传照片的编辑很可能将同一摄影师的几张照片一个接一个地放入队列中。但我们不希望一位摄影师连续数小时拥有主页。

目前,我们手动对队列进行排序,使其尽可能按排队时间顺序 (FIFO),但同一摄影师的两张照片的距离不会超过五个时隙。我们想自动化这个。

我知道我们可以在 PHP 中进行排序,但是我们可以使用单个 MySQL 查询以正确的顺序检索队列吗?

表结构看起来像这样。我们通过交换两个相邻镜头的 queued_time 来对队列进行排序——这并不理想,但它确实有效:

homepage_queue
--------------
id INT NOT NULL
photo INT NOT NULL
queued_time INT NOT NULL

photos
------
id INT NOT NULL
photographer INT NOT NULL

浏览相关的 SO 问题会弹出此页面,这似乎表明我需要模拟 Oracle 的 LAG 功能: http: //onlamp.com/pub/a/mysql/2007/04/12/emulating-analytic-aka-排名功能与 mysql.html?page=2

尤其是当我考虑到我需要查看最后五行时,这看起来很混乱,以至于我很想尖叫着跑开并用 PHP 来做,但是我错过了更简单的方法吗?

我们通常将队列塞满一周,每张照片一个小时,所以我们在外面谈论可能有 200 条记录。

队列末尾肯定有一些照片无法以符合“五分开”规则的方式进行排序。没关系,因为我们很可能每 24 小时运行一次作业,而且随着上传的源源不断,队列的尾端变得一团糟是可以的。

4

2 回答 2

1

确实,当您提出问题时,您应该提供一些有关数据结构的信息。让我假设您在基础表中有以下列:

  • 队列位置
  • 摄影师
  • 照片身份证

如果是这样,以下将根据队列中的第一张照片为每位摄影师返回一行:

select q.*
from Queue q join
     (select PhotographerId, min(QueuePosition) as minQP
      from queue q
      group by PhotographerId
     ) qp
     on q.QueuePosition = minQP
order by q.QueuePosition

以下是您的实际数据的变化:

select q.*
from Queue q join
     (select Photographer, min(QueuedTime) as minQT
      from HomePage_Queue hpq join
           Photos p
           on hpq.PhotoId = p.Id
      group by Photographer
     ) qp
     on q.QueuedTime= minQT
order by q.QueuedTime

假设 QueuedTimes 是唯一的,这将起作用。如果不是,则需要做更多的工作。

于 2012-10-17T19:10:27.183 回答
1

我会在组合中添加另一张表,其中记录了最近出现在您网站上的 5 位摄影师。

查询以选择您的下一张照片:

SELECT
  homepage_queue.photo
FROM
  homepage_queue
INNER JOIN
  photos
    ON photos.id = homepage_queue.photo
LEFT JOIN
  (SELECT photographer, COUNT(*) AS occurances FROM last_five GROUP BY photographer) AS last_five
    ON last_five.photographer = photos.photographer
ORDER BY
  last_five.occurances ASC,
  homepage_queue.queued_time
LIMIT
  1

选择照片后:
- 将该值存储在某处
- 删除最旧的条目last_five
- 添加last_five与新照片的摄影师相关的新条目
- 从队列中删除所选照片

一些额外的维护,但解决方案相对简单并且可以自行维护。

  • 如果队列中只有两名摄影师,他们将交替进行
  • 如果新摄影师上传了几张照片,他们将获得优先权
  • 在最后 5 名中出现次数最少的摄影师总是优先

编辑:

这简化了问题,只关注what's next?

您可以通过在循环中重复该过程 24 次来调整它以生成一个全新的队列。您将每次迭代推入next photo新队列。

您甚至可以一次生成 24 张照片的列表,然后每小时使用一次迭代:
- 删除一张照片
- 使用此方法添加一张照片

然后,您就有了一个包含 24 张照片的固定列表,一种始终将“正确的”添加到列表末尾的方法,并且可以随时重新排列 24 张照片的列表。

于 2012-10-17T19:32:35.440 回答