2016-06-08 79 views
1

正確的輸出我有包括以下表的數據庫:有麻煩了從MySQL查詢

  • 用戶
  • 類別
  • 文章

裏面我們的網站,我們有一個部分稱爲「編輯選擇」,其中有5篇編輯在該領域選擇的最佳文章。

編輯必須設置「is_recommended = yes」和「recommended_location」,它可以是1,2,3,4或5;因此他們將被放置在網站上的1-5個展示位置之一。

文章還有一個「start_date」,意思是作者可以寫一篇文章,將其指定爲is_recommended = yes和recommended_location = 3,然後將其設置爲明天晚上9點。因此這篇文章只會在明天出現,當它出現時,它應該坐在編輯選擇的3盒中。

有時,我們可以具有製品如以下:

  • ID:123
  • is_recommended:是
  • recommended_location = 3
  • 起始日期= 2016年6月5日九時00分00秒(假設這是昨天)

其中目前排名第3。

我有另一篇文章:

  • ID:456
  • is_recommended:是
  • recommended_location = 3
  • 起始日期= 2016年7月5日九點00分00秒(這是今天和今天已經是上午11點)

但是我的查詢仍然顯示ID:123;而我希望它顯示插槽#3是最新的(含義456)

有人可以告訴我我做錯了什麼在我的查詢下面,我怎麼能保證每個插槽最新的項目是選擇?

這是查詢:

select * 
from (
    select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
    from article 
    left join user on article.created_by = user.id 
    left join category on category.id = article.category_id 
    where article.status='active' 
    AND is_recommended='yes' 
    AND article.start_date<='".date('Y-m-d H:i:s')."' 
    AND recommended_location in (1,2,3,4,5) 
    order by start_date desc 
) as x 
group by recommended_location 
limit 5 
+0

即使手動將1天添加到start_date,也應該有end_date比較。這樣你可以使用像BETWEEN start_date和end_date之類的東西...所以在應該返回的行之間沒有混淆。 –

+0

@Turo提供您想要的解決方案。這是你試圖解決的一個不平凡的問題。閱讀[這篇文章](http://www.xaprb.com/blog/2006/12/07/how-to-select-the-firstleastmax-row-per-group-in-sql/)關於試圖解決這個問題問題類型 – AgRizzo

+0

謝謝@AgRizzo這正是問題所在。現在把2 + 2放在一起。 – Hossj

回答

2

您havent't聚集功能,所以你如果只希望每個recommended_location一個文章,你應該使用

不需要按組(最終使用不同的,如果這是你所需要的)

select * 
from ( select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
    from article 
    left join user on article.created_by = user.id 
    left join category on category.id = article.category_id 
    where article.status='active' 
    AND is_recommended='yes' 
    AND article.start_date<='".date('Y-m-d H:i:s')."' 
    AND recommended_location in (1,2,3,4,5) 
    order by start_date desc 
) as x 
limit 5 

(select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
from article 
left join user on article.created_by = user.id 
left join category on category.id = article.category_id 
where article.status='active' 
AND is_recommended='yes' 
AND article.start_date<='".date('Y-m-d H:i:s')."' 
AND recommended_location = '1' 
order by start_date desc limit 1) 
union 
(select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
from article 
left join user on article.created_by = user.id 
left join category on category.id = article.category_id 
where article.status='active' 
AND is_recommended='yes' 
AND article.start_date<='".date('Y-m-d H:i:s')."' 
AND recommended_location = '2' 
order by start_date desc limit 1) 
union 
(select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
from article 
left join user on article.created_by = user.id 
left join category on category.id = article.category_id 
where article.status='active' 
AND is_recommended='yes' 
AND article.start_date<='".date('Y-m-d H:i:s')."' 
AND recommended_location = '3' 
order by start_date desc limit 1) 
union 
(select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
from article 
left join user on article.created_by = user.id 
left join category on category.id = article.category_id 
where article.status='active' 
AND is_recommended='yes' 
AND article.start_date<='".date('Y-m-d H:i:s')."' 
AND recommended_location = '4' 
order by start_date desc limit 1) 
union 
(select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
from article 
left join user on article.created_by = user.id 
left join category on category.id = article.category_id 
where article.status='active' 
AND is_recommended='yes' 
AND article.start_date<='".date('Y-m-d H:i:s')."' 
AND recommended_location = '5' 
order by start_date desc limit 1) 
+0

謝謝。不幸的是,這不會產生正確的結果。 我需要獲取每個recommended_location的最新項目;然而,這個查詢是讓他們隨機放置它們;我現在有兩個項目在1-5被設置爲recommended_location = 3 – Hossj

+0

我已經更新了答案 – scaisEdge

+0

我還沒有檢查這是否工作,但這不會是一個巨大的負載在服務器上?我們網站上有超過10萬用戶,我正試圖尋找優化方法。我知道我們可以緩存,但通常這個查詢至少可以說是很可怕的。 – Hossj

0

試試這個:以降序排列查詢

使用article.id

所以你的查詢是這樣的:

select * 
from (
    select article.*, user.username, category.title as ctitle, user.firstname, user.lastname, category.slug as cslug, category.category_id as pid 
    from article 
    left join user on article.created_by = user.id 
    left join category on category.id = article.category_id 
    where article.status='active' 
    AND is_recommended='yes' 
    AND article.start_date<='".date('Y-m-d H:i:s')."' 
    AND recommended_location in (1,2,3,4,5) 
    order by article.ID desc, recommended_location desc, start_date desc 
) as x 
group by recommended_location 
limit 5 

我希望你能得到解決方案。

+0

感謝你的這一點,不幸的是,它並沒有給我我期待的結果。 – Hossj

1

先進行聚合,然後加入數據,需要

select x.recommended_location, x.start_date, ... 
from 
(select article.recommended_location, max(article.start_date) as start_date 
    from article 
    where article.status='active' 
    AND is_recommended='yes' 
    AND article.start_date<='".date('Y-m-d H:i:s')."' 
    AND recommended_location in (1,2,3,4,5) 
    group by article.recommended_location 
) as x 
inner join article on x.recommended_location = artice.recommended_location  
and x.start_date = article.start_date 
inner join ... 

但我f 2或更多文章具有相同的start_date,您將以這種方式獲得所有文件...