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

0

У меня есть таблица, в которой записывается история обновлений адресов, называемая транзакцией. Схема - это что-то вроде 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 (сообщество). Спасибо.

Теги:
max

4 ответа

2
Лучший ответ

ОБНОВЛЕНО

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
    Я думаю, что вы упустили момент. Адрес может быть нулевым, но он хочет расставить приоритеты, а не нулевые.
  • 0
    да, обновил ...
Показать ещё 4 комментария
3
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.

  • 0
    да, он не нуждается в подзапросе
  • 0
    Я никогда не думал об этом, и это изящная концепция. Как работает порядок, если обновление 1 делает адрес «a», а обновление 2 - адрес «b». Не будет ли сначала отсортировано старое обновление, потому что «a» предшествует «b»?
Показать ещё 8 комментариев
0

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

Выполняя объединение результатов с адресом, а затем результаты, в которых нет адреса, вы можете определить приоритеты и использовать простое подзапрос.

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

  • 0
    Обратите внимание на мое замечание: если вы уверены, что большие значения row_id всегда соответствуют большим значениям transdate, то вы можете использовать row_id, но вы предполагаете, что мне было бы неудобно делать ...
  • 0
    Я уверен, что последний row_id это то, что я после. Поскольку трансдата в этой таблице только гранулирована до уровня секунд, для одного и того же пользователя есть строки с одинаковым трансдатом. Спасибо за ссылку, хотя.
0
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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню