2012-10-17 51 views
2

我有一個照片隊列在一個攝影網站的主頁上顯示。攝影師傾向於一次上傳幾十張照片,這意味着選擇最佳上傳的編輯很可能會將來自同一攝影師的幾張照片一個接一個地放入隊列中。但我們不希望一個攝影師連續數小時擁有該主頁。在SQL中排序:最舊的記錄,但在x行內沒有重複值

目前,我們手動對隊列進行排序,使其儘可能以排隊的時間順序(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-ranking-functions-with-mysql.html?page=2

特別是當我考慮到我需要查看最後五行時,看起來很亂,以至於我試圖逃離尖叫並在PHP中執行它,但是有沒有更簡單的方法?

我們通常會將隊列填滿一週,每張照片一小時,因此我們在外面討論的可能是200條記錄。

在排隊結尾處肯定會有一些照片無法按照「五分開」的規則進行排序。這並不重要,因爲我們可能會每24小時運行一次該作業,並且在穩定的上傳流的情況下,排隊的尾端可能會變得很糟糕。

+0

你是如何管理隊列的?根據我的理解,你從隊列中選出最重要的項目,並在你的網站上顯示一小時。然後你從隊列中選擇下一個項目,顯示一小時。等等。當你從隊列中選擇一個項目時,是否涉及刪除記錄?如果是這樣,你不能只保留已經在網站上的最後5位攝影師的記錄嗎?然後,當您從隊列中選擇最上面的項目時,只需執行'WHERE攝影師不在(SELECT * FROM last_five_photographers)'? * [你確實有**兩個**隊列來維護,但是使用非常簡單的查詢。] * – MatBailie

+0

@Dems儘可能地發揮作用,但我們真的希望事先將隊列排序在最少一天,所以我們知道什麼時候會出現。這使得我們可以根據需要手動重新安排,例如在黃金時段在主頁上看到壯觀的景象,而不是當大多數觀衆睡着時。 –

+0

這實際上不是一個簡單的約束。下一步將取決於之前的情況。這不是什麼*(我相信)*單個查詢即將解決。但是,您可以使用這種方法來構建真正的隊列,通過摺疊排來排隊。但是,如果你只想排列24張照片,循環24次並不會耗費時間。 – MatBailie

回答

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有關新照片的攝影師
- 從隊列中刪除所選照片

有一點額外保留但是這個解決方案相對比較簡單,並且可以維護自己。

  • 如果隊列已滿,只有兩個攝影師,他們會交替
  • 如果一個新的攝影師則上傳了幾張照片後,他們將獲得優先
  • 用最少occurances攝影師在過去的5總是優先

編輯:

這通過僅集中在簡化了問題

您可以通過在一個循環中重複該過程24次來調整它以生成一個全新的隊列。每次迭代,您都會將next photo推送到您的新隊列中。

你甚至可以生成24張該列表一次,然後用單itterations每個小時:
- 刪除一張照片
- 使用這個方法來添加一個照片

然後你有24個恆定的列表照片,一種總是將「正確的一個」添加到列表末尾的方法,以及在任何時候重新排列該列表的能力。

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是唯一的。如果不是,那麼需要做更多的工作。

+0

對不起,是的 - 我意識到,我提交後,並在您回覆時進行編輯。 –

+0

排隊的時間確實是獨一無二的。但是,每個攝影師返回一行可能會讓某個人排隊,但如果攝影師AF全部上傳了三個主頁值得拍攝的照片,那麼攝影師G會上傳一些照片,他的第一個應該是來自其他人的18張照片 - 而不是在他們之後每個人都轉了一圈。如果有必要實現「五分開」的規則,我們只希望有人像這樣跳躍。 –

+1

@EdDaniel。 。 。當我最初閱讀這個問題時,我想我誤解了大約5個部分 - 我認爲這是創建隊列(輸入)而不是輸出的一部分。你可以用一個相當複雜的語句做你想做的事。但是,在幾乎任何其他數據庫中,您都可以使用排序功能,這將大大簡化工作。 –

相關問題