Getting the last record in SQL in WHERE condition

删除回忆录丶 提交于 2019-12-03 13:31:31

Since the 'last' row for ID 1 is neither the minimum nor the maximum, you are living in a state of mild confusion. Rows in a table have no order. So, you should be providing another column, possibly the date/time when each row is inserted, to provide the sequencing of the data. Another option could be a separate, automatically incremented column which records the sequence in which the rows are inserted. Then the query can be written.

If the extra column is called status_id, then you could write:

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

(The table aliases L1 and L2 could be omitted without confusing the DBMS or experienced SQL programmers.)

As it stands, there is no reliable way of knowing which is the last row, so your query is unanswerable.

Does your table happen to have a primary id or a timestamp? If not then what you want is not really possible.

If yes then:

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

I assume that with "last status" you mean the record that was inserted most recently? AFAIK there is no way to make such a query unless you add timestamp into your table where you store the date and time when the record was added. RDBMS don't keep any internal order of the records.

But if last = last inserted, that's not possible for current schema, until a PK addition:

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

Use a data reader. When it exits the while loop it will be on the last row. As the other posters stated unless you put a sort on the query, the row order could change. Even if there is a clustered index on the table it might not return the rows in that order (without a sort on the clustered index).

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

You could also use a ROW_NUMBER() but that requires a sort and you cannot use ROW_NUMBER() directly in the Where. But you can fool it by creating a derived table. The rdr solution above is faster.

In oracle database this is very simple.

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

Hi if this has not been solved yet. To get the last record for any field from a table the easiest way would be to add an ID to each record say pID. Also say that in your table you would like to hhet the last record for each 'Name', run the simple query

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]    

You should now have a table containing the Names in one column and the last available ID for that Name. Now you can use a join to get the other details from your primary table, say this is some price or date then run the following:

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

This should then give you the last records for each Name, for the first record run the same queries as above just replace the Max by Min above.

This should be easy to follow and should run quicker as well

If you don't have any identifying columns you could use to get the insert order. You can always do it like this. But it's hacky, and not very pretty.

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

So basically you get the 'natural order' if you can call it that, and add some column with all the same data. This can be used to sort by the 'natural order', giving you an opportunity to place a row number column on the next query.

Personally, if the system you are using hasn't got a time stamp/identity column, and the current users are using the 'natural order', I would quickly add a column and use this query to create some sort of time stamp/incremental key. Rather than risking having some automation mechanism change the 'natural order', breaking the data needed.

vamsi

I think this code may help you:

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)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!