2014-07-26 32 views
0

在處理WordPress項目時,我有種邊緣情況。我使用高級自定義字段來存儲關於帖子的元數據,這些元數據存儲在「postmeta」表中(而帖子存儲在「post」表中;這裏以「otca_」爲前綴)。ORDER BY子句受另一個表中的子選擇約束

這裏的帖子是強制性evt_date和可能功能evt_date_fin(「fin」代表法語中的「end」,對於跛腳命名約定抱歉)的事件。

我的目標是選擇一系列事件,只保留那些以未來設置的evt_date或將來設置的evt_date_fin(在後一種情況下,不管evt_date爲準)的事件,同時按evt_date排序,因此以分頁,排序的方式顯示它們。

這是我想出了:

$today = date('Ymd'); 
$perPage = 12; 
$offset = $perPage * ($paged-1); // $paged equals 1, 2, … n (the current page) 

$querystr = " 
SELECT SQL_CALC_FOUND_ROWS * FROM otca_posts AS post 
INNER JOIN otca_postmeta AS meta ON (post.ID = meta.post_id) 
WHERE post.post_type = 'agenda' 
AND post.post_status = 'publish' 
AND (
    (meta.meta_key = 'evt_date'  AND CAST(meta.meta_value AS CHAR) >= '". $today ."') 
    OR (meta.meta_key = 'evt_date_fin' AND CAST(meta.meta_value AS CHAR) >= '". $today ."') 
) 
ORDER BY (meta.meta_key = 'evt_date' AND CAST(meta.meta_value AS CHAR)) ASC 
LIMIT ". $perPage ." OFFSET ". $offset; 

$evts = $wpdb->get_results($querystr); 
$total = $wpdb->get_var('SELECT FOUND_ROWS()'); 

// then looping over the $evts and using $perPage/$total to build the pagination links 

因此,對於存儲在otca_post給定後,有幾個記錄在otca_postmeta表引用這篇文章(使用POST_ID),它通過其meta_key不同/ meta_value對(一對用於evt_date,另一個用於evt_date_fin)。我用它們過濾出查詢中的帖子,這很好。

雖然ORDER BY子句實際上不起作用。

我想知道我該如何讓帖子按evt_date排序,這是存儲在otca_postmeta中的一條信息; evt_date不是一行,而是存儲在行「meta_key」中的值,這意味着我需要以某種方式執行子選擇以便......順序。

謝謝。

+1

您是否介意設置一小組數據並從中獲得想要的結果?更好的是,你會創建一個sqlfiddle。 100%確定你會更快得到答案。 –

+0

它看起來像是用'CAST()'丟失了一半布爾表達式。你的意思是將它與某些價值進行比較嗎?在你的order by中,'AND'將導致對於任何非CAST(meta.meta_value AS CHAR)值的非空值返回正布爾值。 –

+0

我_think_你可能正在尋找類似於ORDER BY CASE當meta.meta_key ='evt_date'THEN CAST(meta.meta_value AS CHAR)ELSE NULL END ASC'來有條件地匹配'evt_date'並對其CHAR類型進行排序'meta_value '。如果非匹配首先排序,但您希望它們最後排序,請使用'ZZZ'等高值代替'NULL'... –

回答

1

我在WordPress插件做到這一點相當頻繁 - 你需要加入posts表到postmeta表爲每個你關心的meta_key的,在這種情況下,‘evt_date’和‘evt_date_fin’。一旦你加入他們,你可以在WHERE子句中使用它們來比較DATE(CURRENT_TIMESTAMP)。使用MySql函數STR_TO_DATE()將存儲在meta_value中的字符串轉換爲DATE數據類型 - 本示例假定您使用Y-m-d格式。

$perPage = 12; 
$offset = $perPage * ($paged-1); 

// create the SQL query by joining posts to postmeta 
$querystr = <<<SQL 
    SELECT SQL_CALC_FOUND_ROWS 
     p.*, 
     STR_TO_DATE(s.meta_value, '%Y-%m-%d') AS start_date, 
     STR_TO_DATE(e.meta_value, '%Y-%m-%d') AS end_date 
    FROM otca_posts AS p 
    -- join postmeta for the start 
    JOIN otca_postmeta AS s ON p.ID = s.post_id AND s.meta_key = 'evt_date' 
    -- join postmeta for the end 
    JOIN otca_postmeta AS e ON p.ID = e.post_id AND e.meta_key = 'evt_date_fin' 
    WHERE 
     -- is the start greater than or equal to today? 
     STR_TO_DATE(s.meta_value, '%Y-%m-%d') >= DATE(CURRENT_TIMESTAMP) OR 
     -- or is the end greater than or equal to today? 
     STR_TO_DATE(e.meta_value, '%Y-%m-%d') >= DATE(CURRENT_TIMESTAMP) 
    -- order the results by the start, then the end, then the post title 
    ORDER BY start_date, end_date, p.post_title 
    -- paginate the results 
    LIMIT $perPage OFFSET $offset 
SQL; 

// get posts that match 
$evts = $wpdb->get_results($querystr); 

// get the total number of results 
$total = $wpdb->get_var('SELECT FOUND_ROWS()'); 
+0

謝謝doublesharp。我在查詢中添加了關於帖子類型和狀態的約束,編輯了日期轉換格式(對我來說沒有破折號),而且它完全符合我的需求。我學到了一些SQL。 – chikamichi