所以我有一个表格,其中包含构成主键的2个属性base_id
和sub_id
。该表包含值列表和值有效的日期,如下所示:
base_id | sub_id | validity_start_date | value
---------+--------+---------------------+-------
1 | 1 | 1970-01-01 | 50
1 | 1 | 2000-01-01 | 55
1 | 2 | 1970-02-02 | 50
1 | 2 | 2000-02-02 | 55
1 | 3 | 1970-03-03 | 50
1 | 3 | 2000-03-03 | 55
1 | 4 | 1970-04-04 | 50
1 | 5 | 2015-05-05 | 66
1 | 5 | 2015-06-06 | 70
2 | 4 | 1970-01-01 | 80
2 | 4 | 2015-01-01 | 75
我的目标是为唯一的主键找到最新的有效value
和validity_start_date
,如下所示:
base_id | sub_id | validity_start_date | value
---------+--------+---------------------+-------
1 | 1 | 2000-01-01 | 55
1 | 2 | 2000-02-02 | 55
1 | 3 | 2000-03-03 | 55
1 | 4 | 1970-04-04 | 50
1 | 5 | 2015-06-06 | 70
2 | 4 | 2015-01-01 | 75
为了帮助您,创建代码:
CREATE TABLE `rikai_test` (
`base_id` int(10) unsigned NOT NULL,
`sub_id` int(10) unsigned NOT NULL,
`validity_start_date` date NOT NULL,
`value` tinyint(3) unsigned DEFAULT NULL,
PRIMARY KEY (`base_id`,`sub_id`,`validity_start_date`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `rikai_test` VALUES (1,1,'1970-01-01',50),(1,1,'2000-01-01',55),(1,2,'1970-02-02',50),(1,2,'2000-02-02',55),(1,3,'1970-03-03',50),(1,3,'2000-03-03',55),(1,4,'1970-04-04',50),(1,5,'2015-05-05',66),(1,5,'2015-06-06',70),(2,4,'1970-01-01',80),(2,4,'2015-01-01',75);
按base_id
和sub_id
进行分组或获得绝对最大值没有问题,但我无法将这些组合起来以获得分组的最大值。
答案 0 :(得分:2)
此问题的常见解决方案是使用派生表查找每个组的最大值,并在连接中使用该表,如下所示:
select r.*
from rikai_test r
join (
select base_id, sub_id, max(validity_start_date) max_date
from rikai_test
group by base_id, sub_id
) a on r.base_id = a.base_id
and r.sub_id = a.sub_id
and r.validity_start_date = a.max_date
order by r.base_id, r.sub_id;
结果将是:
base_id sub_id validity_start_date value
1 1 2000-01-01 55
1 2 2000-02-02 55
1 3 2000-03-03 55
1 4 1970-04-04 50
1 5 2015-06-06 70
2 4 2015-01-01 75
答案 1 :(得分:2)
您可以使用左连接where null或者使用group-concat-trick来执行此操作。
第一个是“向我展示那些没有继承者使用相同的base_id,sub_id组合”的数据,这意味着“显示数据不存在更大日期的人”。
select d1.*
from rikai_test d1
left join rikai_test d_not
on d1.base_id = d_not.base_id
and d1.sub_id = d_not.sub_id
and d1.validity_start_date < d_not.validity_start_date
where d_not.base_id is null
当然需要一个非空列(你有)。当然,如果您索引base_id,sub_id并且在一个组合中没有太多值,那么它最有效。使用where not exists (select ...)
甚至可以改善它。
另一个是[正确]类型“给我每组最大的日期,但只是让这个约会带来它的亲戚到党”。所以我们将这个日期和实际值绑定在一起,让mysql最大化这个(因此排序数据必须在concat'ed对的开始处),当两者都达到最大值时,我们可以拆分它们。
select base_id, sub_id, substring(constring, 1, 10) as start_date, substring(constring, 11, length(constring)
from (select base_id, sub_id, max(concat(validity_start_date, value)) as constring group by base_id, sub_id ORDER BY constring) as innerselect
即使是更大的结果也应该非常快。
答案 2 :(得分:-2)
select * from rikai_test
where validity_start_date in
(select max(validity_start_date)
from rikai_test
group by base_id, sub_id)