Получение последней записи в SQL в состоянии WHERE - PullRequest
7 голосов
/ 07 августа 2011

у меня есть 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 из loan_id 1, т. Е. status 4. Пожалуйста, помогите мне в этом запросе.

Ответы [ 9 ]

15 голосов
/ 07 августа 2011

Поскольку последняя строка для идентификатора 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.)

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

5 голосов
/ 07 августа 2011

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

Если да, то:

    SELECT TOP 1 status
    FROM loanTable
    WHERE loan_id = 1
    ORDER BY primaryId DESC
    -- or
    -- ORDER BY yourTimestamp DESC
4 голосов
/ 07 августа 2011

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

2 голосов
/ 07 августа 2011

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

select top 1 status, loan_id
from loanTable
where loan_id = 1
order by id desc -- PK
0 голосов
/ 19 декабря 2016

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

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 голосов
/ 05 августа 2015

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

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 голосов
/ 06 января 2014

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

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

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 голосов
/ 19 августа 2013

В базе данных oracle это очень просто.

выберите * из (выберите * из заказа loanTable по rownum desc), где rownum = 1

0 голосов
/ 07 августа 2011

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

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

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

...