2011-08-07 188 views
5

我有loanTable含有两个领域loan_idstatus获取最后一条记录在SQL中的WHERE条件

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即Statusstatus 4.可以帮我在这个查询中。

+3

如果没有“序列”列或日期或东西,你永远无法找到以一致的方式“最后”的地位。根据你的表索引的方式,如果你的查询计划将使用多个CPU等等,你将得到不一致的结果。 –

+0

这实际上是可能的。如果你真的想要它,我可以为你制作一个sql。虽然这似乎是一个奇怪的要求。但我想它对于一个从未被插入的其他东西感动的日志表很有用。 –

+0

我真的很抱歉我有问过这个问题。我不知道这件事,并真的被设置为投票 –

回答

12

由于ID'的'最后'行既不是最小值也不是最大值,因此您处于轻微混淆状态。表中的行没有顺序。因此,您应该提供另一列,可能是每行插入的日期/时间,以提供数据的排序。另一个选项可以是一个单独的,自动递增的列,用于记录行插入的顺序。然后可以写入查询。

如果额外列名为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程序员省略。)

因为它站立,没有可靠的方式知道哪一个是最后一行,所以你的查询是无法回答的。

+1

谢谢你可能我不知道这一个我应该寻找另一列看看它的最大值 –

2

但如果最后=最后插入的,这是不可能的电流模式,直到PK此外:

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

我不是在寻找这一个。为什么按状态desc命令我不明白。其实我正在查看loan_id 1的最后一个状态。 –

+0

根据OP的请求,两个查询都不返回'4' - 两个都会返回'6'。 – ain

+0

此查询帮助我检索表格中的最新日期。 –

5

请问你的表恰好有一个主ID或时间戳?如果没有,那么你想要的是不可能的。

如果是的话:

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

我认为用“最后的状态”你的意思是插入最近的记录? AFAIK没有办法做出这样的查询,除非你添加时间戳记到你的表格中存储添加记录的日期和时间。 RDBMS不保留记录的任何内部顺序。

0

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

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

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

0

在oracle数据库中这很简单。

SELECT * FROM(SELECT * FROM loanTable ORDER BY ROWNUM递减),其中的rownum = 1

0

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

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即可。

这应该很容易跟随,并应跑得快以及

0

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

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 

所以基本上你会得到'自然顺序',如果你可以调用它,并添加一些列与所有相同的数据。这可用于按“自然顺序”进行排序,让您有机会在下一个查询中放置行号列。个人而言,如果您正在使用的系统没有时间戳/标识列,并且当前用户正在使用'自然顺序',我会快速添加一列并使用此查询来创建某种类型的时间戳/增量键。不要冒着冒着某种自动化机制改变“自然秩序”的风险,打破所需的数据。

0

我觉得这个代码可以帮助你:

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) 
+0

添加一些解释与答案如何这个答案帮助OP在解决当前问题 –

相关问题