2011-10-27 134 views
0

有關此主題的StackOverflow的前一個問題(可以插入鏈接,目前我沒有權限),標題爲「MySQL日期比較過濾器」,這是作爲一。MySQL日期/作者比較

我在我的WordPress博客上有一些作者,我想通過MySQL獲得他們的生產力。接下來的查詢工作得很好,在MySQL下在一定的時間範圍內只有一天獲得一個作者的帖子:

SELECT  SQL_CALC_FOUND_ROWS wp_posts.* 
FROM  wp_posts 
    JOIN  wp_postmeta 
    ON  (wp_posts.ID = wp_postmeta.post_id) 
WHERE  wp_posts.post_type = 'post' 
    AND  post_author = '50' 
    AND  post_date 
    BETWEEN STR_TO_DATE('2011-10-27 14:19:17','%Y-%m-%d %H:%i:%s') 
     AND STR_TO_DATE('2011-10-27 14:51:17','%Y-%m-%d %H:%i:%s') 
GROUP BY wp_posts.ID 
ORDER BY wp_posts.post_date DESC 
LIMIT  0, 100 

但它給我的那一天正好職位,小時範圍內。我想得到一張桌子,每天和每位作者的日常數據都已填滿。在每一天和每位作者中,應該有該作者在該日和該小時範圍內發佈的帖子數量。

輸出應該是這樣的:

October Auth1 Auth2 Auth3 
1 0 0 0 
2 0 0 0 
3 0 1 0 
4 0 2 0 
5 1 0 0 
6 0 2 0 
7 0 0 0 
8 3 0 0 
9 0 0 0 
10 5 1 0 
11 1 0 0 
... 
31 2 1 1 

所以日期應該是一個變量,但我想,包括所有的作者,所以我刪除post_author和線路。

我不是MySQL的專家,但我想知道這是否可以輕鬆完成,並將查詢結果(或者更準確地說是查詢結果的某些字段)作爲表格導出,如所示。

回答

1

我認爲你應該創建一個日期參考表,填充該表,然後從該表中查找LEFT OUTER JOIN。 「我如何顯示錯過的日期?」的問題是相當的common SO question,但我會去爲它。

預賽步驟

在MySQL提示符運行:

use WordPress; 

步驟1 - 創建日期參考表

create table all_date 
(id int unsigned not null primary key auto_increment, 
a_date date not null, 
last_modified timestamp not null default current_timestamp on update current_timestamp, 
unique key `all_date_uidx1` (a_date)); 

第2步 - 填充日期參考表

此表的想法是每個日期都有一行。現在你可以通過運行插入語句來實現這一點,但爲什麼不寫一個例程來爲你填充它(你可以創建一個MySQL scheduled event以確保你在表中總是有一組完整的日期。下面是對該例程的建議:

DELIMITER // 


CREATE PROCEDURE populate_all_dates(IN from_date DATE, IN days_into_future INT) 

BEGIN 

DECLARE v_date DATE; 
DECLARE ix int; 


SET ix := 0; 
SET v_date := from_date; 


WHILE v_date <= (from_date + interval days_into_future day) DO 

    insert into all_date (a_date) values (v_date) 
    on duplicate key update last_modified = now(); 

    set ix := ix +1; 

    set v_date := from_date + interval ix day; 

END WHILE; 

END// 

DELIMITER ; 

您現在可以運行:

call populate_all_dates('2011-10-01',30); 

要填充的所有日期爲十月(或剛殺青到任何你想要的days_into_the_future參數)

現在你有一個。日期refe

select day(a.a_date) as 'October', 
IFNULL(t.a1,0) as 'Auth1', 
IFNULL(t.a2,0) as 'Auth2', 
IFNULL(t.a50,0) as 'Auth50' 
from all_date a 
LEFT OUTER JOIN 
(
SELECT date(wp.post_date) as post_date, 
sum(case when wp.post_author = '1' then 1 else 0 end) as a1, 
sum(case when wp.post_author = '2' then 1 else 0 end) as a2, 
sum(case when wp.post_author = '50' then 1 else 0 end) as a50, 
count(*) as 'All Auths' 
FROM wp_posts wp 
WHERE wp.post_type = 'post' 
AND wp.post_date between '2011-10-01' and '2011-10-31 23:59:59' 
GROUP BY date(wp.post_date) 
) t 
ON a.a_date = t.post_date 
where a.a_date between '2011-10-01' and '2011-10-31' 
group by day(a.a_date); 
+0

哇,這看起來很有希望Tom Mac,感謝您付出的巨大努力。我很害怕我不是MySQL的專家所以...我如何運行這個?一旦我在mysql提示符下,我只是複製並粘貼這些代碼片段? 對不起:( – javipas

+0

)如果你在提示時是的,你應該可以將它們作爲代碼片段運行,在運行它們之前,你需要選擇一個模式來運行它們,我猜wp_posts和wp_postmeta是在WordPress模式中,所以運行'use WordPress ;'在運行上面的任何一個之前,我會編輯我的答案以向你展示我的意思 –

+0

Tom Mac,我測試了你的代碼,它似乎工作......或多或少。我的WordPress數據庫(我在WordPress博客o中使用的數據庫)的名稱改變了'使用WordPress'所以在嘗試使用你的代碼(「WHERE p_posts.post_type ='post'」應該是「WHERE wp_posts.post_type ='post'」)我得到了一些結果,但不是預期的。 事實上,表格顯示了我與作者的三個colums,但是帖子數量非常高,有一天Auth1發佈了94篇文章,Auth50發佈了145篇是不可能的。 – javipas

1

我不打算重寫整個查詢,但這裏是你會怎麼做數據分組:

SELECT ... 
FROM ... 
WHERE YEAR(post_date) = 2011 AND MONTH(post_date) = 10 
GROUP BY DAY(post_date), HOUR(post_date) 

每個作者創建多個列是沒有很好的利用的查詢。這種轉換在你的wordpress代碼中更好。

請注意,此查詢將在精確的時鐘週期,上午1點,凌晨2點,凌晨3點等工作...如果您需要任意時間(上午1:05,上午2:05,上午3:05等)將無法正常工作,您需要更復雜的分組。

+0

我affraid這不是我一直在尋找:這給了我們有序的職位名單與您感興趣的人口,你可以繼續運行查詢十月所有日期倫斯表按日期和小時,但這是我在Wordpress帖子列表上得到的相同,可以按作者和月份過濾。 – javipas

+0

就像我說的,我不打算重寫你的查詢。我曾經深入研究過WP的大腸桿菌,而且從未像現在這樣相同,所以我不會再去查看它的數據庫來找出真正的查詢應該是什麼。只是顯示你如何做日期/時間分組。 –

+0

夠公平,但那個分組不是我所需要的。不管怎麼說,還是要謝謝你! – javipas

0

以下查詢將按作者分組發帖數量。

SELECT  DAY(post_date) as d, MONTH(post_date) as m, YEAR(post_date) as y, post_author, COUNT(id) as c 
FROM  wp_posts 
    JOIN  wp_postmeta 
    ON  (wp_posts.ID = wp_postmeta.post_id) 
WHERE  wp_posts.post_type = 'post' 
    AND  post_date 
    BETWEEN STR_TO_DATE('2011-10-27 14:19:17','%Y-%m-%d %H:%i:%s') 
     AND STR_TO_DATE('2011-10-27 14:51:17','%Y-%m-%d %H:%i:%s') 
GROUP BY d, m, y, post_author 
ORDER BY y, m, d, post_author 
LIMIT  0, 100 

這將輸出就像一個表:

d m y post_author c 
------------------------------------ 
2 10 2011 50 23 
2 10 2011 51 12 
2 10 2011 52 6 

意爲例如第1行:在2011年10月2日作者ID爲50 23個職位。您將首先獲取數組中的作者以形成表格的標題。然後用PHP迭代這個結果,你可以生成一個表格,就像你想要的那樣放置's和'。

+0

只需添加註釋:如果在某一天沒有任何作者的帖子,那一天將不會出現在結果中,因此您應該使用PHP覆蓋此情況。 –

+0

Nedret,感謝您的提示:我剛剛測試過這個查詢,但它沒有給出預期的結果。計算COUNT(id)參數是否錯誤?我爲「c」列獲得了奇怪的值,就好像日期範圍沒有被照顧一樣。我認爲它顯示了10月份發佈的所有帖子,而不僅僅是我試圖指定的日期和時間範圍。例如,2011年10月27日,只有作者「50」從14:30到18:30發佈了三篇文章。當我運行我的查詢(問題中的答案)時,答案是確定的,但是如果我運行查詢,它會顯示我發佈的113篇文章...奇怪:( – javipas