【问题标题】:Mysql: get highest of one and lowest value of another field in one rowMysql:在一行中获取一个字段的最大值和另一个字段的最小值
【发布时间】:2012-05-27 22:25:32
【问题描述】:

我有一个 (MySQL) 表,其中包含两个日期/时间字段:startend(每个类型均为 datetime)。我需要一个查询,它为某个用户和定义的日期提供start 的最低值和end 的最高值。我终于成功了以下查询:

SELECT job.id, job.user_id, job.start, last.end 
FROM job
    JOIN job AS last 
        ON job.user_id = last.user_id 
            AND DATE( job.start ) = DATE( last.start ) 
            AND last.end = (SELECT max( last2.end) 
                            FROM job AS last2 
                            WHERE last2.user_id = last.user_id 
                                AND DATE( last2.end ) = DATE( last.end ))
WHERE job.user_id = 1 
    AND DATE( job.start ) = '2012-05-28' 
ORDER BY job.start ASC 
LIMIT 0,1

即使它有效,但它并不“感觉”正确。有没有更简单的方法来做到这一点? 非常感谢任何帮助和提示。谢谢!

示例数据:

user_id     start               end
1       2012-05-28 07:13:00     2011-04-26 07:45:00
1       2012-05-28 08:15:00     2011-04-26 08:50:00
1       2012-05-28 05:32:00     2011-04-26 05:51:00
1       2012-05-28 08:50:00     2011-04-26 09:50:00
1       2012-05-28 15:10:00     2011-04-26 15:40:00
1       2012-05-27 16:11:00     2011-04-26 16:46:00
2       2012-05-28 09:50:00     2011-04-26 10:35:00

【问题讨论】:

  • DATE( job.start ) ??? job.start 列是什么类型的?
  • 一些示例数据和预期输出将大大帮助我们帮助您。
  • 按 job.start 排序不返回从 start 开始的最小值。它返回给定用户的所有值开始的最低值开始。如果给定用户有两行作业具有相同的结束日期,则它们都将被返回。
  • 如果你用 LIMIT 0,1 将它限制为一个值,它会返回最小值
  • 同一个user_id应该有多行?我认为这意味着为每个 user_id 显示一次最低起点和最高终点

标签: mysql max min


【解决方案1】:
Select user_id
  , Min( start ) As MinStart
  , Max( end ) As MaxEnd
From job
Where Date( start ) = '2012-05-28'
  And user_id = 1
Group By user_id, Date( start )

根据您的评论,{1, 2012-5-28 5:32:00 2011-04-26 15:40:00} 是预期输出(这就是示例输出如此重要的原因),这表明开始和结束日期值不一定与实际行的值相关。例如,样本数据中没有包含值组合的行。鉴于此,解决方案更简单。

我对@9​​87654324@ 进行分组只是为了表明,如果您删除 Where 子句,您可以按开始日期确定最小和最大开始日期。鉴于您对两者都进行过滤,您可以将查询简化为:

Select user_id
  , Min( start ) As MinStart
  , Max( end ) As MaxEnd
From job
Where Date( start ) = '2012-05-28'
  And user_id = 1
Group By user_id

SQL Fiddle版本

【讨论】:

    【解决方案2】:
    SELECT job.user_id,min(job.start) AS orderby,max(job.end)
    FROM job
    WHERE job.user_id=1
    GROUP BY job.user_id
    HAVING DATE(job.start)='2012-05-28'
    ORDER BY orderby
    LIMIT 1
    

    未经测试,希望它对你有用,并且更有意义。

    通过使用聚合函数,我们可以轻松找到最小值和最大值,但是我必须取出(或者我可以包含,但会使查询变得相当复杂)的是 job.id。如果需要包含它,则必须使用子查询来选择具有该 user_id 的作业,并且 job.start 与最小值匹配。

    【讨论】:

    • 感谢您的提示,但它似乎不起作用,因为开始的最小值在一行,而结束的最大值在另一行。
    • 这很奇怪,这正是我认为它应该工作的原因。 group by 允许我们轻松处理许多不同的行,只要 user_id 相同。然后我们可以使用聚合函数 min 和 max 来选择我们想要的。到底是怎么回事?
    • 这意味着问题出在 HAVING 状态。您可能必须包含小时:分钟:秒或更改比较类型。
    • 存在 start = NULL 的行,这似乎导致了问题。有没有办法排除所有 start = NULL 的行?
    • 我猜你可以在 WHERE 子句中添加 job.start IS NOT NULL,虽然我不确定为什么会出现问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 2011-07-13
    • 2021-05-15
    • 1970-01-01
    • 2021-12-21
    相关资源
    最近更新 更多