【问题标题】:Retrieve only last record of each group between range仅检索范围之间每个组的最后一条记录
【发布时间】:2021-08-10 00:12:31
【问题描述】:

我的桌子是

+-------+----------------+---------+--------------+-------------------+
|  id   | invoice_number | user_id | created_date | next_contact_date |
+-------+----------------+---------+--------------+-------------------+
| 42699 |            100 |     236 | 2021-05-19   | 2022-08-09        |
| 42693 |            100 |     236 | 2021-03-01   | 2022-08-09        |
| 42694 |            100 |      30 | 2021-03-01   | 2022-08-08        |
| 42695 |            100 |     235 | 2021-03-03   | 2022-08-09        |
| 42696 |            100 |      30 | 2021-05-01   | 2022-08-02        |
| 42697 |            100 |     235 | 2021-05-03   | 2022-08-04        |
| 42698 |            100 |     236 | 2021-05-04   | 2022-08-02        |
| 42700 |            100 |      30 | 2021-05-19   | 2022-08-08        |
| 42701 |            100 |     235 | 2021-05-20   | 2022-08-08        |
| 42702 |            100 |     236 | 2021-05-19   | 2022-08-09        |
+-------+----------------+---------+--------------+-------------------+

我想根据每个 user_id 组的 id 检索最后一条记录,但前提是它在 next_contact_date 范围之间

期望的输出

如果用户选择检索 2022-08-012022-08-15 之间的记录,则应该是

+-------+----------------+---------+--------------+-------------------+
|  id   | invoice_number | user_id | created_date | next_contact_date |
+-------+----------------+---------+--------------+-------------------+
| 42700 |            100 |      30 | 2021-05-19   | 2022-08-08        |
| 42701 |            100 |     235 | 2021-05-20   | 2022-08-08        |
| 42702 |            100 |     236 | 2021-05-19   | 2022-08-09        |
+-------+----------------+---------+--------------+-------------------+

效果很好!!!!

如果现在用户选择检索 2022-08-012022-08-05 之间的记录,它应该是 EMPTY,因为每个 user_id 组的最后一个 id 不在里面next_contact_date。

我的尝试

SELECT * FROM mytable WHERE id IN 
                    (SELECT MAX(id) AS id FROM mytable where mytable.next_contact_date BETWEEN '2022-08-01' AND '2022-08-05 23:59:59.999' GROUP BY user_id)

我得到的结果不是我想要的。结果应该是空的,因为最后的记录不属于用户指定的 next_contact_date 范围。

+-------+----------------+---------+-----------------+-------------------+
|  id   | invoice_number | user_id |    created_date | next_contact_date |
+-------+----------------+---------+-----------------+-------------------+
| 42696 |            100 |      30 | 2021-05-01      | 2022-08-02        |
| 42697 |            100 |     235 | 2021-05-03      | 2022-08-04        |
| 42698 |            100 |     236 | 2021-05-04      | 2022-08-02        |
+-------+----------------+---------+-----------------+-------------------+

【问题讨论】:

  • 但请注意,以SELECT * 开头并以GROUP BY ... 结尾的一切都不会顺利
  • 你有 3 个 user_ids,我不明白为什么 30 是 goubled
  • 这就是为什么我们喜欢结构良好的问题并提供有关如何构建它们的信息。
  • @nbk 我很抱歉这是创建帖子时的错误。
  • @Strawberry 对不起,我不想失礼。为什么你认为我的问题结构不完善?我读了你给我的文章,我没有看到我做了任何与它所说的不同的事情

标签: mysql group-by inner-join


【解决方案1】:

您需要进一步的子查询来捕获所有在该时间范围内选择的 user_id。

并使用 user_ids 获取最后一个 id,但只选择时间范围内的那些行

CREATE TABLE mytable
    (`id` int, `invoice_number` int, `user_id` int, `created_date` date, `next_contact_date` date)
;
    
INSERT INTO mytable
    (`id`, `invoice_number`, `user_id`, `created_date`, `next_contact_date`)
VALUES
    (42699, 100, 236, '2021-05-19', '2022-08-09'),
    (42693, 100, 236, '2021-03-01', '2022-08-09'),
    (42694, 100, 30, '2021-03-01', '2022-08-08'),
    (42695, 100, 235, '2021-03-03', '2022-08-09'),
    (42696, 100, 30, '2021-05-01', '2022-08-02'),
    (42697, 100, 235, '2021-05-03', '2022-08-04'),
    (42698, 100, 236, '2021-05-04', '2022-08-02'),
    (42700, 100, 30, '2021-05-19', '2022-08-08'),
    (42701, 100, 235, '2021-05-20', '2022-08-08'),
    (42702, 100, 236, '2021-05-19', '2022-08-09')
;
SELECT * FROM mytable WHERE id IN 
                    (SELECT MAX(id) AS id FROM mytable 
                    where `user_id` IN 
                    (SELECT `user_id` FROM mytable WHERE mytable.next_contact_date BETWEEN '2022-08-01' AND '2022-08-05 23:59:59.999')
                    GROUP BY user_id)
AND mytable.next_contact_date BETWEEN '2022-08-01' AND '2022-08-05 23:59:59.999'
编号 |发票号码 |用户 ID |创建日期 | next_contact_date -: | -------------: | ------: | :----------- | :----------------
SELECT * FROM mytable WHERE id IN 
                    (SELECT MAX(id) AS id FROM mytable 
                    where `user_id` IN 
                    (SELECT `user_id` FROM mytable 
                    WHERE mytable.next_contact_date BETWEEN '2022-08-01' AND '2022-08-15 23:59:59.999')
                    GROUP BY user_id)
AND mytable.next_contact_date BETWEEN '2022-08-01' AND '2022-08-15 23:59:59.999'
编号 |发票号码 |用户 ID |创建日期 | next_contact_date ----: | -------------: | ------: | :----------- | :---------------- 42700 | 100 | 30 | 2021-05-19 | 2022-08-08 42701 | 100 | 235 | 2021-05-20 | 2022-08-08 42702 | 100 | 236 | 2021-05-19 | 2022-08-09

db小提琴here

【讨论】:

  • 尝试在 2022-08-01 和 2022-08-05 之间更改搜索它不会返回每个 user_id 组的最后记录
  • 哦,是的,它确实如此,因为有多三行,每行左一见dbfiddle.uk/…
  • 不...这些记录不是每个 user_id 的最后一个。最后记录是 user_id = 30 的 42700、user_id = 235 的 42701 和 user_id = 236 的 42702。
  • 不,它们不是因为您只选择 2022-08-01 和 2022-08-05 之间的行,并且链接中只剩下 3 行。 Mysql 采用您在 where 子句中所做的选择并应用分组依据。或在无关紧要时完全跳过日期
  • 是的,你是对的。然而,要求是,当且仅当这些记录 next_contact_date 列值在用户提供的日期之间时,我才需要携带最新记录。
猜你喜欢
  • 2010-11-21
相关资源
最近更新 更多