【问题标题】:Get values of first record and last record by date in mysql subquery在mysql子查询中按日期获取第一条记录和最后一条记录的值
【发布时间】:2018-02-20 00:31:14
【问题描述】:

我知道对于一些 MySQL 专业人士来说,这相当简单。我进一步意识到答案可能是figured out from other answers,但是我花了一些时间尝试构建此查询,但我似乎无法弄清楚如何将这些解决方案应用于我的情况。

我的 似乎与其他想要字段“最小值和最大值”的人不同 - 但我需要基于“最小值和最大值”的 另一个字段 的值日期字段。

给定以下结构 - 一个“用户”表和一个“条目”表:

数据样本(用于“条目”表):

id | user_id |     date     | value  
---+---------+--------------+-------
 1         1     2018-02-01     125
 2         5     2018-01-15     220
 3         1     2017-12-31     131
 4         4     2018-01-01      77
 3         1     2017-12-15     133

我想知道第一个条目的值(按日期)最后一个条目的值(按日期)和 user_id。

结果应该是:

user_id | first_date | first_value |  last_date | last_value
--------+------------+-------------+------------+-----------
      1   2017-12-15           133   2018-02-01          125
      4   2018-01-01            77   2018-01-01          133
      5   2018-01-15           220   2018-01-15          220

虽然我想要最好的解决方案,但我一直致力于将一些查询组合起来,如下所示:

SELECT user_id, l.date AS last_date, l.value AS last_value, f.date AS first_date, f.value AS first_value  
    FROM user AS u
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1) AS f ON f.user_id = u.user_id
    LEFT JOIN (SELECT user_id, date, value FROM entries ORDER BY date DESC LIMIT 1) AS l ON l.user_id = u.user_id

注意:这不起作用。如果我想要某人的“第一个条目”,我会编写一个查询 SELECT user_id, date, value FROM entries ORDER BY date ASC LIMIT 1 - 但是,在子查询中使用它不会产生预期的效果。

我也尝试了一些GROUP BY 查询,也没有成功。

SQL 小提琴:http://sqlfiddle.com/#!9/71599

【问题讨论】:

标签: mysql subquery mariadb


【解决方案1】:

以下查询为您提供了预期的结果,但它没有使用LEFT JOIN。因此,NULL 值被排除在外。

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM 
    users u, 
    (SELECT * FROM entries e ORDER BY date ASC) e1,
    (SELECT * FROM entries e ORDER BY date DESC) e2
WHERE
    e1.user_id = u.id
AND 
    e2.user_id = u.id
GROUP BY 
    u.id

这是一个有效的小提琴 - http://sqlfiddle.com/#!9/71599/8

另外,值得注意的是,您尝试使用 LIMIT 会将所有连接结果的结果限制为 1,而不是每个连接结果。无论哪种方式,LEFT JOIN 都不起作用。如果有人知道原因,我很想了解。

编辑:这是另一个尝试,这次使用MIN()MAX(),而不是ORDER BY。不幸的是,您需要多次加入 entries 表才能使其正常工作。

SELECT 
    u.id AS user_id,
    e1.date AS first_date,
    e1.value AS first_value,
    e2.date AS last_date,
    e2.value AS last_value
FROM users u
INNER JOIN entries e1 ON (u.id = e1.user_id)
INNER JOIN entries e2 ON (u.id = e2.user_id)
INNER JOIN (
    SELECT user_id, MIN(date) AS date
    FROM entries
    GROUP BY user_id
) e3 ON (e1.user_id = e3.user_id AND e1.date = e3.date)
INNER JOIN (
    SELECT user_id, MAX(date) AS date
    FROM entries
    GROUP BY user_id
) e4 ON (e2.user_id = e4.user_id AND e2.date = e4.date)
GROUP BY u.id

另一个工作小提琴:http://sqlfiddle.com/#!9/71599/18

【讨论】:

  • 再次感谢您。知道为什么这不能通过 PHPMyAdmin 在 MariaDB 上运行吗?我为“第一个”和“最后一个”获得了相同的记录/值。
  • 从快速的谷歌上,听起来 MariaDB 忽略了子查询中的 ORDER BY 子句。回到绘图板。
  • @cale_b - 我添加了另一个示例,它不使用ORDER BY。这可能解决了 MariaDB 的问题,但我还没有在那个 RDBMS 上专门测试它。
  • 非常感谢。第二个例子完美运行(让我觉得不是我自己整理出来的不那么愚蠢)。
猜你喜欢
  • 2019-12-28
  • 1970-01-01
  • 2017-05-08
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多