SQL - получить последнюю строку с данными в определенном столбце или только последнюю строку, если в этом столбце нет данных - PullRequest
0 голосов
/ 25 августа 2010

У меня есть таблица, в которой записывается история обновлений адресов, называемая транзакцией. Схема является чем-то вроде row_id (int, PK), user_id (int), address1 (varchar), transdate (timestamp).

Я хочу запросить таблицу и получить одну строку, возвращаемую пользователю, показывающую, какая строка является последней (т.е. наибольшая временная метка), но если в столбце address1 есть данные, мне нужна последняя строка с данными. Если в этом столбце нет данных, просто последняя строка.

Пример:

row_id    user_id    address1        transdate
1         70005      56 The Street   2010-08-25 09:15
2         70005      NULL            2010-08-25 10:04
3         70005      12 Some Road    2010-08-25 11:17
4         70005      NULL            2010-08-25 12:18

С запросом типа

SELECT  user_id, address1 
FROM    transaction t 
WHERE   user_id = 70005 
        AND row_id = 
            (SELECT MAX(row_id) 
             FROM transaction ti 
             WHERE ti.user_id = t.user_id)

возвращаемый результат будет

user_id    address1
70005      NULL

но я хочу

user_id    address1
70005      12 Some Road

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

Надеюсь, это имеет смысл. У кого-нибудь есть предложения?

Я использую MySQL 5.1.49 (сообщество). Спасибо.

Ответы [ 4 ]

3 голосов
/ 25 августа 2010
SELECT    user_id, address1 
FROM      transaction
WHERE     user_id = 70005
ORDER BY  ISNULL(address1) ASC, row_id DESC
LIMIT     1

Это должно расставлять приоритеты строк с данными, все еще работая, когда address1 равно NULL.Я бы также использовал transdate вместо row_id.

2 голосов
/ 25 августа 2010

ОБНОВЛЕНО

SELECT  user_id, address1 
FROM    transaction t 
WHERE   user_id = 70005 
    AND row_id = 
        IFNULL(
          (SELECT MAX(row_id) 
         FROM transaction ti 
         WHERE ti.user_id = t.user_id AND address1 IS NOT NULL),

         (SELECT MAX(row_id) 
         FROM transaction ti 
         WHERE ti.user_id = t.user_id ) 
        );
0 голосов
/ 25 августа 2010
SELECT  user_id, address1
FROM    transaction t  
WHERE   user_id = 70005 
ORDER BY case when address1 is not null then 0 else 1 end, transdate desc
limit 1
0 голосов
/ 25 августа 2010

Посмотрите на принятый ответ на этот вопрос (не мой ответ, он был лучше)

Объединяя результаты с адресом, а затем результаты, где естьбез адреса, вы можете расставить приоритеты и по-прежнему использовать простое объединение подзапросов.

Обратите внимание, что вы получаете максимальный row_id, а не максимальную дату, поэтому вы не получите ожидаемых результатов, даже еслиВы делаете это.

...