【问题标题】:How can I find the oldest ticket that is not closed? [closed]如何找到未关闭的最旧票? [关闭]
【发布时间】:2015-09-23 17:51:29
【问题描述】:

我有一张桌子:

Ticket #      SubmitDate    Status
    101        1/1/2015     Closed
    102        1/1/2015     Closed
    103        1/1/2015     Closed
    104        1/2/2015      Open
    105        1/2/2015     Closed
    106        1/2/2015      Open
    107        1/2/2015      Open
    108        1/2/2015     Closed
    109        1/3/2015     Closed
    110        1/4/2015      Open
    111        1/5/2015     Closed
    112        1/5/2015     Closed
    113        1/5/2015      Open
    114        1/5/2015      Open
    115        1/5/2015      Open

我正在尝试查找仍处于打开状态的最旧票。 我知道 MIN(SubmitDate) 会得到最旧的 SubmitDate,但我无法将查询放在一起。

新编辑: 大家好。我正在修改这个问题,所以它更清楚。我向任何认为这令人困惑的人道歉。我迫于压力要立即得到答案,所以我太仓促了。

我正在尝试确定仍处于“打开”状态的最旧票号。 我一直在做错事:

这是我失败的查询之一:

SELECT

MIN(SubmitDate) as [Date Submitted]
,(SELECT FROM TicketTable WHERE Status = 'Open' AND SubmitDate = MIN(SubmitDate)) as [Ticket #]
,Status as [Status]

FROM TicketTable

我想要达到的结果是:

Date Submitted  Ticket #    Status
1/2/2015          104        Open

再次,我深表歉意。我从来没有打算简单地得到答案。我只是希望得到一个提示。再次感谢大家。

【问题讨论】:

  • SELECT MIN(Date) FROM Table WHERE Status='Open'
  • @JonH 这只会为您提供日期,而不是其他请求的列
  • 这也不是答案..
  • 我投票决定将此问题作为题外话结束,因为似乎没有任何真正的努力试图解决这个问题。我不觉得引用MIN(SubmitDate) 构成了寻找解决方案的真正努力。向我们展示一些失败的查询尝试会让我有不同的感觉。
  • 这有助于我们判断是否进行了真正的尝试。对我来说,这几乎像是一项与 Gimme the Codez 接壤的家庭作业。其他人可能不同意真正努力的解释,因为它是主观的,我尊重这一点。

标签: sql sql-server


【解决方案1】:
select top 1 * from table
where "status" = 'Open'
order by "SubmitDate" asc ;

在 SQL Server 2012+ 版本中,您还可以使用(标准)offset - fetch 语法,替换 top

select * from table
where "status" = 'Open'
order by "SubmitDate" asc 
offset 0 rows
fetch first 1 row only ;

【讨论】:

  • 你为什么不直接使用 MIN ?
  • @JonH 您如何使用MIN 并获得比此查询更简单的所需结果?
  • 这是最简单的方法!
  • 非常简单的答案。无需使用 MIN
  • @jonh,所需的结果包含表的所有字段。 TOP 1 是最简单的方法,因为它不需要子查询。
【解决方案2】:
select top 1 * from Table where Status = 'Open' order by SubmitDate desc 

【讨论】:

    【解决方案3】:

    SubmitDate 上使用带有order by 子句的row_number() 可以解决问题。

    select SubmitDate, [Ticket #], Status
      from (select t.*,
                   row_number() over (order by SubmitDate) as rn
              from mytable t
             where t.Status = 'Open') x
     where x.rn = 1
    

    【讨论】:

    • 这里有很多不必要的 SQL。它完成了工作,但做事效率很低……为什么要子查询?为什么要从子查询中选择 *?子查询的重点不是隐藏 RN 吗?
    • @Hituptony:因为stb 的出色答案在我写这篇文章时并没有浮现在脑海中 :)
    • 我喜欢。这不是“最佳”答案,因为您无法在这个问题上击败 SELECT TOP 1...,但如果每个状态都需要 Min(Date) ...
    • 好多了! @sstan 干得好!
    【解决方案4】:

    如您所见,您的大部分答案都是这种格式。我个人认为这是最严格的,读起来就像它说的那样没有混淆嵌套查询和使用分钟。

    SELECT TOP 1 * 
    FROM 
        YourTable 
    WHERE 
        Status = 'Open'
    ORDER BY
        SubmitDate Desc
    

    【讨论】:

      【解决方案5】:

      我只需要在已经很棒的列表中添加另一个:

      SELECT * 
      FROM table
      WHERE submitDate IN (SELECT min(SubmitDate) FROM table WHERE status = 'Open')
      

      不过,就个人而言,我会选择@STB 的SELECT TOP 1... 路线,因为这很可能是该组中表现最好的。其余的将依赖于子查询,这意味着数据库两次访问表(包括这个)。

      但是...只是想分享一下有很多方法可以解决它

      【讨论】:

      • 请注意,您的结果可能与 TOP 1 方法不同,因为它不使用 WITH TIES - 因此其他答案将始终恰好得到一行,而您的结果可能返回具有相同 submitDate 的多行。
      • 实际上,如果最早的未决票证与已关闭票证的日期相同,则此查询可能会返回错误结果。
      • @sstan 哦,是的,我错过了那部分
      • 确实如此。我在写的时候是这样想的;但是,鉴于表中的数据,它会正常工作。这是一个有趣的问题。 :)
      • @JNevill “给定表中的数据” - 所以你假设 OP 实际上只有 15 行,现在是只读的?
      【解决方案6】:

      SQL Fiddle Demo

      SELECT *
      FROM YourTable Y,
          (SELECT  MIN(SubmitDate) mDate
          FROM YourTable
          WHERE Status = 'Open') as T
      WHERE Y.SubmitDate = T.mDate
        AND Status = 'Open'
      

      【讨论】:

      • @Hituptony 是的,我看到现在有更好的方法。但这是我第一次坚持 :(
      • 如果最早的未决票证与已关闭票证的日期相同,则此查询可能会返回错误结果。
      • @sstan 我再次修复它。现在更加复杂:(与最佳答案相比,这不是我的最佳选择。唯一的事情是我的归还关系。
      猜你喜欢
      • 1970-01-01
      • 2015-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多