Получение последней записи в SQL в условии WHERE

Я loanTable, которые содержат два поля loan_id и status

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

в этой ситуации мне нужно показать последнего Status of loan_id 1 i.e is status 4. Пожалуйста, помогите мне в этом запросе.

9 ответов


поскольку "последняя" строка для 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 могут быть опущены без путаницы СУБД или опытных программистов SQL.)

в его нынешнем виде нет надежного способа узнать, какая строка является последней, поэтому ваш запрос неразрешим.


у вашей таблицы есть основной идентификатор или временная метка? Если нет, то чего вы хотите на самом деле не возможно.

если да, то:

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

Я предполагаю, что с "последним статусом" Вы имеете в виду запись, которая была вставлена совсем недавно? AFAIK нет способа сделать такой запрос, если вы не добавите метку времени в таблицу, где вы храните дату и время добавления записи. РСУБД не ведут никакого внутреннего порядка записей.


но если last = last inserted, это невозможно для текущей схемы до добавления PK:

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

используйте устройство чтения данных. Когда он выйдет из цикла while, он будет находиться в последней строке. Как указывали другие плакаты, если вы не поместите сортировку в запрос, порядок строк может измениться. Даже если в таблице есть кластеризованный индекс, он может не возвращать строки в этом порядке (без сортировки по кластеризованному индексу).

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

вы также можете использовать ROW_NUMBER () но для этого требуется сортировка, и вы не можете использовать ROW_NUMBER () непосредственно в Where. Но вы можете обмануть его, создав производный таблица. Решение rdr выше быстрее.


в базе данных Oracle-это очень просто.

select * from (select * from loanTable order by rownum desc) где rownum=1


Привет, если это еще не решено. Чтобы получить последнюю запись для любого поля из таблицы, самый простой способ-добавить идентификатор к каждой записи, скажем 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]    

теперь у вас должна быть таблица, содержащая имена в одном столбце и последний доступный идентификатор для этого имени. Теперь вы можете использовать соединение, чтобы получить другие данные из основной таблицы, скажем, это какая-то цена или дата затем выполните следующие действия:

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 выше.

Это должно быть легко следовать, и должны работать быстрее, а также


Если у вас нет идентифицирующих столбцов, которые можно использовать для получения порядка вставки. Ты всегда можешь сделать так. Но это не очень красиво и не очень.

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

Итак, в основном вы получаете "естественный порядок", если вы можете его так назвать, и добавляете столбец со всеми теми же данными. Это можно использовать для сортировки по "естественному порядку", давая вам возможность разместить столбец номера строки в следующем запросе.

лично, если система, которую вы используете не имеет времени столбец stamp / identity, а текущие пользователи используют "естественный порядок", я бы быстро добавил столбец и использовал этот запрос для создания своего рода временной метки/инкрементного ключа. Вместо того, чтобы рисковать иметь какой-то механизм автоматизации изменить "естественный порядок", нарушая необходимые данные.


Я думаю, что этот код может помочь вам:

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)