繁体   English   中英

在MySQL中将上一行子查询转换为联接

[英]Converting Previous Row Subquery into a Join in MySQL

我在策略表中有策略信息。 每行表示特定时间的策略状态(时间存储在updated_on列中)。 每行都属于一个策略迭代(多个策略行可以属于一个策略迭代)。 我想查看策略迭代中各行之间的状态变化。

策略表:

CREATE TABLE `policy` (
  `policy_id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `policy_iteration_id` int(10) unsigned NOT NULL,
  `policy_status_id` tinyint(3) unsigned NOT NULL,
  `updated_on` datetime NOT NULL,
  PRIMARY KEY (`policy_id`),
  KEY `policy_iteration_idx` (`policy_iteration_id`),
  KEY `policy_status_updated_idx` (`policy_status_id`,`updated_on`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

我希望能够传递日期范围以及“从”状态和“至”状态,并返回“至”行的策略数据。 因此,在伪代码中,我需要按策略迭代分组,找到满足数据范围和“至”状态的行,然后查看该策略迭代中的上一行,以查看其是否具有“从”状态。 如果是这样,则返回“至”行的信息。

这是我想出的查询:

SELECT
    pto.policy_iteration_id,
    pto.policy_id,
    pto.updated_on,
FROM
    policy AS pto
WHERE
    pto.updated_on >= $from_date AND
    pto.updated_on <= $to_date AND
    pto.policy_status_id = $to_status_id AND
    $from_status_id = 
    (SELECT
        pfrom.policy_status_id
    FROM
        policy AS pfrom
    WHERE
        pfrom.policy_iteration_id = pto.policy_iteration_id AND
        pfrom.policy_id < pto.policy_id
    ORDER BY
        pfrom.policy_id DESC
    LIMIT
        1);

该查询有效,但是效率非常低,因为必须为每一行执行子查询。 我想通过使用子查询联接来提高效率,但是我不知道怎么做。

任何帮助,将不胜感激。 谢谢!

更新1

为了帮助解释我要做什么,这是一个示例数据集:

+-----------+---------------------+------------------+---------------------+
| policy_id | policy_iteration_id | policy_status_id | updated_on          |
+-----------+---------------------+------------------+---------------------+
|    323705 |               27230 |                6 | 2014-08-01 10:27:11 |
|    325028 |               27230 |                2 | 2014-08-01 17:12:28 |
|    323999 |               27591 |                2 | 2014-08-01 12:07:31 |
|    324008 |               27591 |                6 | 2014-08-01 12:10:23 |
|    325909 |               27591 |                2 | 2014-08-02 14:59:12 |
|    327116 |               29083 |                6 | 2014-08-04 12:09:16 | 
|    327142 |               29083 |                6 | 2014-08-04 12:19:00 |
|    328067 |               29083 |                2 | 2014-08-04 17:58:41 |
|    327740 |               29666 |                3 | 2014-08-04 16:16:55 |
|    327749 |               29666 |                3 | 2014-08-04 16:19:01 |
+-----------+---------------------+------------------+---------------------+

现在,如果我运行from_date ='2014-08-02 00:00:00',to_date ='2014-08-05 00:00:00',from_status = 6和to_status = 2的查询,结果应为:

+-----------+---------------------+------------------+---------------------+
| policy_id | policy_iteration_id | policy_status_id | updated_on          |
+-----------+---------------------+------------------+---------------------+
|    325909 |               27591 |                2 | 2014-08-02 14:59:12 |
|    328067 |               29083 |                2 | 2014-08-04 17:58:41 |
+-----------+---------------------+------------------+---------------------+

这两行在指定的时间段内具有选择的“ to_status”为2的行,而其前一行的“ from_status”为6。

我不认为可以将MAX策略ID与GROUP BY的policy_iteration_id结合使用,因为这样做会返回最新的行,而不是返回带有“ to_status”的行之前的行。

任何进一步的帮助,将不胜感激。 谢谢!

您可以使用use max from.policy_id where from.policy_id < to.policy_id有助于将上一行作为一个集合。

select
        p.policy_iteration_id,
        p.policy_id,
        p.updated_on
from 
    policy f
        inner join (
    select
        p.policy_iteration_id,
        p.policy_id,
        p.updated_on,
        max(f.policy_id) as prev_policy_id
    from
        policy p
            inner join 
        policy f 
            on f.policy_iteration_id = p.policy_iteration_id and
               f.policy_id < p.policy_id
    where
        p.updated_on >= $from_date and
        p.updated_on <= $to_date and
        p.policy_status_id = $to_status_id
    group by
        p.policy_iteration_id,
        p.policy_id,
        p.updated_on
) p
        on p.prev_policy_id = f.policy_id
where
    f.policy_status_id = $from_status_id

在具有窗口功能的数据库中,有更简单的方法可以实现此目的。

示例SQLFiddle

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM