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)