2011-11-22 44 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