我有一个表,可以按日期跟踪联系人类状态的变化。我想回答的问题是某个日期所有联系人的当前状态是什么。
DROP TABLE IF EXISTS `contact_class_state`;
CREATE TABLE `contact_class_state` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`contact_id` int unsigned DEFAULT NULL, -- the contact
`contact_class` int unsigned,
`state_date` date,
PRIMARY KEY (`id`),
INDEX (`contact_id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `contact_class_state` (`contact_id`, `contact_class`, `state_date`) VALUES
(1, 1, '2011-01-01'),
(2, 1, '2011-01-01'),
(3, 1, '2011-01-01'),
(4, 1, '2011-01-01'),
(5, 1, '2011-01-01'),
(1, 2, '2011-02-01'),
(3, 2, '2011-02-01'),
(5, 2, '2011-02-01'),
(1, 1, '2011-02-15'),
(5, 3, '2011-03-01');
例如,以下查询:
SELECT contact_id, contact_class, state_date
FROM contact_class_state
WHERE state_date <= '2011-02-27'
ORDER BY contact_id, state_date DESC
返回
+------------+---------------+------------+
| contact_id | contact_class | state_date |
+------------+---------------+------------+
| 1 | 1 | 2011-02-15 |
| 1 | 2 | 2011-02-01 |
| 1 | 1 | 2011-01-01 |
| 2 | 1 | 2011-01-01 |
| 3 | 2 | 2011-02-01 |
| 3 | 1 | 2011-01-01 |
| 4 | 1 | 2011-01-01 |
| 5 | 2 | 2011-02-01 |
| 5 | 1 | 2011-01-01 |
+------------+---------------+------------+
虽然这在技术上是正确的,但我只需要每个contact_id的第一行(或最后排序的ASC)行,因为最新的日期总是会给我当前的联系状态,如下所示:
+------------+---------------+------------+
| contact_id | contact_class | state_date |
+------------+---------------+------------+
| 1 | 1 | 2011-02-15 |
| 2 | 1 | 2011-01-01 |
| 3 | 2 | 2011-02-01 |
| 4 | 1 | 2011-01-01 |
| 5 | 2 | 2011-02-01 |
+------------+---------------+------------+
我很确定一个子查询或一个复杂的查询可以解决问题,但我正在使用SQL进行心理阻塞。我也对其他解决这个问题的方法持开放态度。
谢谢!
答案 0 :(得分:0)
如果您的查询实际上是您想要的(除了然后按contact_id分组),那么就这样做。
SELECT * FROM
(SELECT contact_id, contact_class, state_date
FROM contact_class_state
WHERE state_date <= '2011-02-27'
ORDER BY contact_id, state_date DESC) table1
GROUP BY contact_id
经过测试,效果很好。