Mysql 查询一个报表的两个表(高级)

Mysql 查询一个报表的两个表(高级),mysql,sql,join,Mysql,Sql,Join,我在使用高级SQL查询时遇到了一些问题,而且我已经很久没有使用SQL数据库了。我们使用MySQL 背景: 我们将使用两个表: “交易表” 表:历史记录 +---------------+-----------------------------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default |

我在使用高级SQL查询时遇到了一些问题,而且我已经很久没有使用SQL数据库了。我们使用MySQL

背景:

我们将使用两个表:

“交易表”

表:历史记录

+---------------+-----------------------------+------+-----+-------------------+-------+    
| 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_序数包含“信息”表中的复合键,“事务”表中的m_id、m_a_序数和a_过期日期字段也包含复合键

实际上,当记录过期时,信息表中的a_state字段将更新为expired。同时,在transactions表中创建一条记录,其中包含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~~

本质上,我需要构建一个报告来显示过期的所有方面,无论是手动过期还是自然过期

此报告应该从上面的查询中获取数据,并将其与“信息表”上的另一个查询相结合,该查询表示某个日期是否过期 语法可能有点错误,没有时间测试;但你可以从这里得到要点,我希望:

同样,coalesce只返回一系列值中的第一个非空值。如果你只处理两个NULLIF,它也可以工作

语法可能有点错误,没有时间测试;但你可以从这里得到要点,我希望:


同样,coalesce只返回一系列值中的第一个非空值。如果您只处理两个null,则可能也会起作用。

Hmm。。我看不出信息表中哪里有“过期”日期。我们少了一张桌子吗?我会计划选择从信息左侧连接到事务过期的事务,然后合并(事务过期日期、项目过期日期)的所有内容。我如何知道“自然过期日期”是什么?或者怎么计算呢?哎呀。很抱歉我删掉了一些不相关的栏目。让我很快更新一下。很抱歉。另外,自然失效日期是出版日期后2年。让我为您插入这两列。关于您的第一个评论,我不能加入到事务过期的位置,因为当事务自然过期时,软件不会将信息表中的状态更改为过期:(…我已经试过了。除非我遗漏了什么。如果你需要一个例子,我可以向你展示特定的查询数据。嗯……我看不出信息表在哪里有“过期”日期。我们在这里遗漏了一个表吗?我会计划选择从信息左连接到事务过期的事务的所有内容,然后合并数据(交易到期日、项目到期日)我如何知道“自然到期日”是什么是吗?或者如何计算?哎呀。对不起。我删掉了一些不相关的栏目。让我很快更新它。对不起。另外,自然过期日期比发布日期晚2年。让我为您插入这两个栏目。关于您的第一条评论,我不能加入他们讨论事务在哪里过期,因为当它过期时,自然软件不会在信息表中将状态更改为“过期”:(…我已经试过了。除非我遗漏了什么。如果您需要示例,我可以向您显示特定的查询数据。很抱歉,响应延迟--我休假了。我如上所述运行了查询,但它返回的行数与刚过期的历史记录上的原始查询相同,因此它不会合并结果(对于自然过期的记录和已终止的记录)。:(对于延迟响应,我感到抱歉——我休假了。我如上所述运行了查询,但它返回的行数与原始查询的just 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++
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;