Mysql 有条件的最大值

Mysql 有条件的最大值,mysql,Mysql,我有一张表格,代表团体中的个人成员资格: +----+-----------+----------+------------+------------+ | id | person_id | group_id | from | to | +----+-----------+----------+------------+------------+ | 1 | 1 | 1 | 2014-10-13 | 2014-10-20 | +----

我有一张表格,代表团体中的个人成员资格:

+----+-----------+----------+------------+------------+
| id | person_id | group_id | from       | to         |
+----+-----------+----------+------------+------------+
| 1  | 1         | 1        | 2014-10-13 | 2014-10-20 |
+----+-----------+----------+------------+------------+
| 2  | 1         | 1        | 2014-10-17 | 2014-10-31 |
+----+-----------+----------+------------+------------+
| 3  | 1         | 1        | 2014-10-01 | 2014-10-15 |
+----+-----------+----------+------------+------------+
| 4  | 1         | 2        | 2014-11-01 | 2014-12-01 |
+----+-----------+----------+------------+------------+
我想为每个组和个人选择组合成员资格,以及显示其当前是否处于活动状态的状态。如果结果中没有合并当前“非活动”成员身份与“活动”成员身份重叠的成员身份,这是可以的(尽管如果这也是可能的话)。今天是2014年10月17日,因此本案例的结果集应为:

+-----------+----------+------------+------------+----------+
| person_id | group_id | from       | until      | status   |
+-----------+----------+------------+------------+----------+
| 1         | 1        | 2014-10-13 | 2014-10-31 | ACTIVE   |
+-----------+----------+------------+------------+----------+
| 1         | 2        | NULL       | NULL       | INACTIVE |
+-----------+----------+------------+------------+----------+
因此,对于第1组,使用的值为第1行的
,第2行的
,第3行被排除,即使其
与第1行的
重叠。我更希望使用第3行中的
from
,但如果结果集如上面所示,则没有问题。组2处于非活动状态,因为它没有任何带有
from
直到>NOW()的行

现在我有这个:

CREATE TEMPORARY TABLE combinedRows ENGINE = MEMORY
SELECT
    `person_id`,
    `group_id`,
    MIN(`from`) AS `from`,
    MAX(`until`) AS `until`,
    'ACTIVE' AS `status`
FROM
    `memberships`
WHERE
    `person_id` = @updated_person
    AND `group_id` = @updated_bgroup
    AND `from` < NOW()
    AND `until` > NOW()
GROUP BY
    `person_id`,
    `group_id`;
创建临时表combinedRows引擎=内存
挑选
`人名`,
`组id`,
MIN(`from`)作为`from`,
MAX(`until`)作为`until`,
“活动”作为“状态”`
从…起
`会员资格`
哪里
`person\u id`=@updated\u person
和'group\u id`=@updated\u bgroup
和'from`现在()
分组
`人名`,
`组id`;
然后插入忽略到combinedRows中选择反转。。。基本上,我希望在单个查询中执行相同的操作(出于性能原因)。与此“伪代码”等价的东西:

创建临时表combinedRows引擎=内存
挑选
`人名`,
`组id`,
MIN(`from`WHERE`from`NOW())默认为`from`,
MAX(`until`WHERE`from`NOW())默认为`until`,
如果(*something*,'ACTIVE','INACTIVE')作为'status'`
从…起
`会员资格`
哪里
`person\u id`=@updated\u person
和'group\u id`=@updated\u bgroup
分组
`人名`,
`组id`;
这可能吗??还是我应该忘记它,不担心性能?还是应该以某种方式更改数据库设计

SELECT
  `person_id`,
  `group_id`,
  MIN(CASE WHEN `from` < NOW() and `until` > NOW() THEN `from` ELSE NULL END) AS `from`,
  MAX(CASE WHEN `from` < NOW() and `until` > NOW() THEN `until` ELSE NULL END) AS `until`,
  MIN(CASE WHEN `from` < NOW() and `until` > NOW() THEN 'ACTIVE' ELSE 'INACTIVE' END) AS `status`
FROM
  `memberships`
WHERE
  `person_id` = @updated_person
  AND `group_id` = @updated_bgroup
GROUP BY
  `person_id`,
  `group_id`;
这里的技巧是:如果有满足条件的行,则返回“ACTIVE”,因为与字符串相比,“ACTIVE”小于“INACTIVE”

SELECT
  `person_id`,
  `group_id`,
  MIN(CASE WHEN `from` < NOW() and `until` > NOW() THEN `from` ELSE NULL END) AS `from`,
  MAX(CASE WHEN `from` < NOW() and `until` > NOW() THEN `until` ELSE NULL END) AS `until`,
  MIN(CASE WHEN `from` < NOW() and `until` > NOW() THEN 'ACTIVE' ELSE 'INACTIVE' END) AS `status`
FROM
  `memberships`
WHERE
  `person_id` = @updated_person
  AND `group_id` = @updated_bgroup
GROUP BY
  `person_id`,
  `group_id`;
MIN(CASE WHEN `from` < NOW() and `until` > NOW() THEN 'ACTIVE' ELSE 'INACTIVE' END)