【问题标题】:Getting the last record in SQL in WHERE condition在 WHERE 条件下获取 SQL 中的最后一条记录
【发布时间】:2011-10-21 18:51:06
【问题描述】:

我有 loanTable 包含两个字段 loan_idstatus

loan_id status
==============
1       0
2       9
1       6
5       3
4       5
1       4  <-- How do I select this??
4       6

在这种情况下,我需要显示loan_id 1 的最后一个Status,即status 4。请在此查询中帮助我。

【问题讨论】:

  • 如果没有“序列”列或日期或其他内容,您永远无法以一致的方式找到“最后”状态。取决于您的表的索引方式,如果您的查询计划将使用多个 cpu 等。您将得到不一致的结果。
  • 其实是可以的。如果你真的想要它,我可以为你制作一个 sql。虽然这似乎是一个奇怪的要求。但我想它对于除了插入之外从未接触过任何其他东西的日志表可能很有用。
  • 对于我提出的问题,我真的很抱歉。我不知道这件事,真的准备投反对票

标签: sql sql-server tsql where-clause


【解决方案1】:

但如果 last = 最后插入,则对于当前架构是不可能的,直到添加 PK:

select top 1 status, loan_id
from loanTable
where loan_id = 1
order by id desc -- PK

【讨论】:

  • 我不是在找这个。为什么按状态描述订购我不明白。实际上我正在查看loan_id 1 的最后状态。
  • 根据 OP 的请求,两个查询都不会返回 4 - 两者都将返回 6
  • 此查询帮助我检索表中的最新日期。
【解决方案2】:

您的表是否恰好有主 ID 或时间戳?如果没有,那么你想要的就不可能了。

如果是,那么:

    SELECT TOP 1 status
    FROM loanTable
    WHERE loan_id = 1
    ORDER BY primaryId DESC
    -- or
    -- ORDER BY yourTimestamp DESC

【讨论】:

    【解决方案3】:

    我假设“最后状态”是指最近插入的记录? AFAIK 没有办法进行这样的查询,除非您将时间戳添加到您存储添加记录时的日期和时间的表中。 RDBMS 不保留记录的任何内部顺序。

    【讨论】:

      【解决方案4】:

      由于 ID 1 的“最后”行既不是最小值也不是最大值,因此您生活在一种轻度混乱的状态中。表中的行没有顺序。因此,您应该提供另一列,可能是插入每一行的日期/时间,以提供数据的排序。另一种选择可能是一个单独的、自动递增的列,它记录插入行的顺序。然后就可以编写查询了。

      如果额外的列被称为status_id,那么你可以这样写:

      SELECT L1.*
        FROM LoanTable AS L1
       WHERE L1.Status_ID = (SELECT MAX(Status_ID)
                               FROM LoanTable AS L2
                              WHERE L2.Loan_ID = 1);
      

      (可以省略表别名 L1 和 L2,而不会混淆 DBMS 或有经验的 SQL 程序员。)

      就目前而言,没有可靠的方法知道哪一行是最后一行,因此您的查询无法回答。

      【讨论】:

      • 谢谢,我可能不知道这个我可能应该寻找另一列来看看它的最大值
      【解决方案5】:

      使用数据阅读器。当它退出 while 循环时,它将位于最后一行。正如其他海报所说,除非您对查询进行排序,否则行顺序可能会改变。即使表上有聚集索引,它也可能不会按该顺序返回行(没有对聚集索引进行排序)。

          SqlDataReader rdr = SQLcmd.ExecuteReader();
          while (rdr.Read())
          {
          }
          string lastVal = rdr[0].ToString()
          rdr.Close();
      

      您也可以使用 ROW_NUMBER(),但这需要排序,并且您不能直接在 Where 中使用 ROW_NUMBER()。但是您可以通过创建派生表来欺骗它。上面的 rdr 解决方案更快。

      【讨论】:

        【解决方案6】:

        在oracle数据库中这很简单。

        select * from (select * from loanTable order by rownum desc) where rownum=1

        【讨论】:

          【解决方案7】:

          嗨,如果这还没有解决。 要从表中获取任何字段的最后一条记录,最简单的方法是为每条记录添加一个 ID,例如 pID。还要说,在您的表中,您想为每个“名称”添加最后一条记录,运行简单查询

          SELECT Name, MAX(pID) as LastID
          INTO [TableName]
          FROM [YourTableName]
          GROUP BY [Name]/[Any other field you would like your last records to appear by]    
          

          您现在应该有一个表格,其中包含一列中的名称和该名称的最后一个可用 ID。 现在您可以使用连接从主表中获取其他详细信息,例如这是某个价格或日期,然后运行以下命令:

          SELECT a.*,b.Price/b.date/b.[Whatever other field you want]
          FROM [TableName] a LEFT JOIN [YourTableName] 
          ON a.Name = b.Name and a.LastID = b.pID
          

          这应该会为您提供每个名称的最后一条记录,对于第一条记录运行与上面相同的查询,只需将上面的 Max 替换为 Min。

          这应该很容易理解并且应该运行得更快

          【讨论】:

            【解决方案8】:

            如果您没有任何可用于获取插入顺序的标识列。你总是可以这样做。但它很hacky,而且不是很漂亮。

            select
            t.row1,
            t.row2,
            ROW_NUMBER() OVER (ORDER BY t.[count]) AS rownum from (
            select 
                tab.row1,
                tab.row2,
                1 as [count] 
            from table tab) t
            

            所以基本上你会得到'自然顺序',如果你可以称之为,并添加一些包含所有相同数据的列。这可用于按“自然顺序”排序,让您有机会在下一个查询中放置行号列。

            就个人而言,如果您使用的系统没有时间戳/身份列,并且当前用户正在使用“自然顺序”,我会快速添加一列并使用此查询来创建某种时间戳/增量键。而不是冒着让一些自动化机制改变“自然顺序”、破坏所需数据的风险。

            【讨论】:

              【解决方案9】:

              我认为这段代码可以帮助你:

              WITH cte_Loans
              AS
              (
              SELECT   LoanID
                      ,[Status]
                      ,ROW_NUMBER() OVER(ORDER BY (SELECT 1)) AS RN
              FROM    LoanTable
              )
              
              SELECT   LoanID
                      ,[Status]
              FROM    LoanTable L1
              WHERE   RN = (  SELECT max(RN)
                              FROM LoanTable L2
                              WHERE L2.LoanID = L1.LoanID)
              

              【讨论】:

              • 添加一些解释,说明此答案如何帮助 OP 解决当前问题
              猜你喜欢
              • 1970-01-01
              • 2020-01-31
              • 1970-01-01
              • 2014-03-09
              • 1970-01-01
              • 2019-12-28
              • 2015-01-29
              • 1970-01-01
              • 2021-06-25
              相关资源
              最近更新 更多