【问题标题】:MySQL subquery/complex query question, tracking state changesMySQL子查询/复杂查询问题,跟踪状态变化
【发布时间】:2011-09-27 21:45:17
【问题描述】:

我有一张按日期跟踪联系人类别状态变化的表格。我试图回答的问题是某个日期所有联系人的当前状态是什么。

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 有心理障碍。我也对解决此问题的其他方法持开放态度。

谢谢!

【问题讨论】:

    标签: mysql sql


    【解决方案1】:

    如果您的查询实际上是您想要的(按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
    

    这是经过测试的,效果很好。

    【讨论】:

    • 也许我遗漏了一些东西,但你有需要子选择的理由吗?
    • 谢谢!我在不使用子查询的情况下玩弄 GROUP BY。现在说得通了。如果有人有建议,我也愿意接受完全不同的方法。
    • @Dave 您需要首先获得所需的结果,然后按联系人分组以获得每个联系人的第一个结果集。您下面的解决方案没有返回正确的contact_class。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    • 2012-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多