2011-11-22 43 views
1

我在高級SQL查詢方面遇到了一些麻煩,而且我已經使用SQL數據庫很長時間了。我們使用MySQL。在兩個表格上查詢一個報告(高級)

背景:

我們將與兩個表進行工作:

「事務表」

表:expire_history

+---------------+-----------------------------+------+-----+-------------------+-------+  
| Field   | Type      | Null | Key | Default   | Extra | 
+---------------+-----------------------------+------+-----+-------------------+-------+ 
| m_id   | int(11)      | NO | PRI | 0     |  | 
| m_a_ordinal | int(11)      | NO | PRI | 0     |  | 
| a_expired_date| datetime     | NO | PRI |     |  | 
| a_state  | enum('EXPIRED','UNEXPIRED') | YES |  | NULL    |  | 
| t_note  | text      | YES |  | NULL    |  | 
| t_updated_by | varchar(40)     | NO |  |     |  | 
| t_last_update | timestamp     | NO |  | CURRENT_TIMESTAMP |  | 
+---------------+-----------------------------+------+-----+-------------------+-------+ 

「信息表」

表:信息

+---------------------+---------------+------+-----+---------------------+-------+ 
| Field    | Type   | Null | Key | Default    | Extra | 
+---------------------+---------------+------+-----+---------------------+-------+ 
| m_id    | int(11)  | NO | PRI | 0     |  | 
| m_a_ordinal   | int(11)  | NO | PRI | 0     |  | 
| a_type    | varchar(15) | YES | MUL | NULL    |  | 
| a_class    | varchar(15) | YES | MUL | NULL    |  | 
| a_state    | varchar(15) | YES | MUL | NULL    |  | 
| a_publish_date  | datetime  | YES |  | NULL    |  | 
| a_expire_date  | date   | YES |  | NULL    |  | 
| a_updated_by  | varchar(20) | NO |  |      |  | 
| a_last_update  | timestamp  | NO |  | CURRENT_TIMESTAMP |  | 
+---------------------+---------------+------+-----+---------------------+-------+ 

我們有一套一個表中描述記錄中的字段。每條記錄都包含一個m_id(人)和一個序數(一個人可以有多個記錄)。例如,我的m_id可以是1,我可以有多個序號(1,2,3,4等),每個序號都有自己的一組數據。 m_id和m_a_ordinal在「信息」表中包含組合鍵,「transactions」表中的m_id,m_a_ordinal和a_expired_date字段也包含組合鍵。

本質上,當我們到期一條記錄時,信息表中的a_state字段會更新爲過期。同時,使用m_id,m_a_ordinal和a_expired_date在交易表中創建記錄。我們已經在過去,人們會不耐煩並可以點擊兩次按鈕找到,所以通過以前的一些幫助,我已經成功地縮小最近的事務,爲每個以下查詢過期記錄:

SELECT e1.m_id, e1.m_a_ordinal, e1.a_expired_date, e1.t_note, e1.t_updated_by 
FROM expire_history e1 
    INNER JOIN (SELECT m_id, m_a_ordinal, MAX(a_expired_date) AS a_expired_date 
    FROM expire_history GROUP BY m_id, m_a_ordinal) e2 
    ON (e2.m_id = e1.m_id AND e2.m_a_ordinal = e1.m_a_ordinal AND e2.a_expired_date = e1.a_expired_date) 
WHERE e2.a_expired_date > '2008-05-15 00:00:00' ORDER BY a_date_expired; 

似乎很簡單,對吧?

讓我們添加一些複雜性。 「信息」表中的每條記錄都有一個「自然失效日期」。然而,我們軟件的原始開發人員沒有編寫代碼來將記錄的狀態在達到自然失效日期時更改爲「過期」。它也不會在交易表過期時將事務寫入交易表(我的理解是,因爲這只是記錄某個人過期的記錄,而不是自動記錄)。另外,手動記錄過期時,原始到期日期不會更改。這就是爲什麼這麼複雜:P ~~。

本質上,我需要構建一個報告,顯示過期的所有方面,無論是手動過期還是自然過期。

這份報告應該從上面的查詢數據,並與上說,如果a_expire_date < = CURDATE顯示記錄的「信息表」另一個查詢(以上來自expire_history查詢)結合了它,除非在記錄exisits,然後顯示來自(在expire_history查詢)的記錄。

的原始邏輯的一個粗略的結構如下:

for x in record_total 
    if (m_id m_a_ordinal) exists in expire_history 
     display m_id, m_a_ordinal, a_expired_date, a_state) 
    else if (m_id_a_ordinal) exists in information AND a_expire_date <= CURDATE 
     display (m_id, m_a_ordinal, a_expire_date, a_state) 
    end if 
x++ 

我希望這是不夠簡潔。

感謝您提供任何幫助!

+0

嗯..我沒有看到信息表中有「過期」日期。我們在這裏錯過了一張桌子嗎?我打算選擇從左邊加入信息到交易爲EXPIRED的交易,然後合併(交易過期日期,商品到期日期) – xQbert

+0

我如何知道「自然到期日期」是什麼?或者如何計算它? – xQbert

+0

oops。抱歉。我刪除了一些不相關的列。讓我更快速地更新它。對於那個很抱歉。 – mattai

回答

1
SELECT i.m_id, I.m_a_ordinal, 
    coalesce(e1.a_expired_date, I.A_Expire_Date) as Expire_DT, 
    coalesce(e1.t_note,'insert related item column'), 
    coalesce(e1.t_updated_by, I.A_Updated_by) as Updated_By 
FROM Information I 
    LEFT JOIN expire_history e1 
     ON E1.M_ID = I.M_ID 
     AND I.m_a_ordinal=e1.M_a_ordinal 
    INNER JOIN 
     (SELECT m_id, m_a_ordinal, MAX(a_expired_date) AS a_expired_date 
     FROM expire_history GROUP BY m_id, m_a_ordinal) e2 
     ON (e2.m_id = e1.m_id 
     AND e2.m_a_ordinal = e1.m_a_ordinal 
     AND e2.a_expired_date = e1.a_expired_date) 
WHERE coalesce(e2.a_expired_date,i.A_Expire_Date) > '2008-05-15 00:00:00' 
ORDER BY a_date_expired; 

語法可能有點不對,有時候要測試;但你可以從中得到它的要點,我希望:

再次,合併做的只是返回一系列值中的第一個非空值。如果你只處理兩個NULLIF也可以。

+0

對不起延遲的迴應 - 我已經出去度假了,我跑瞭如上所述查詢,但它返回與expire_history上的原始查詢相同數量的行,所以它不會合並結果(自然過期的記錄和已被殺死的記錄)。:( – mattai