SQL: ВЫБРАТЬ строки с максимальной датой из созданной таблицы - PullRequest
1 голос
/ 16 февраля 2020

Мне интересно, как создать запрос, который возвращает SERIALID, QTY, но только для последнего INVOICEDATE.

Для объединения информации из двух таблиц я использую UNION.

SELECT ab.SERIALID, ab.QTY, ab.INVOICEDATE
FROM (SELECT a.INVOICEDATE, a.SERIALID, a.QTY
      FROM SALESTRANS a
      UNION
      SELECT b.INVOICEDATE, b.SERIALID, b.QTY
      FROM SERVICETRANS b
     ) ab

У меня есть две таблицы, объединенные с UNION, и моя таблица выглядит так:

Table AB

Я хотел бы сделать запрос, который возвращает SERIALID, QTY, но только за последний INVOICEDDATE.

Результат, который я хотел бы получить:

Result

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

Если ваша СУБД поддерживает ROW_NUMBER(), вы можете добиться этого, используя ROW_NUMBER() PARTITION BY, как показано ниже.

SELECT *
FROM (
    SELECT *
        ,ROW_NUMBER() OVER (
            PARTITION BY SERIALID ORDER BY INVOICEDATE DESC
            ) RN
    FROM SERVICETRANS
    ) T
WHERE RN = 1

Вышеупомянутый запрос вернет вам 1 запись для каждой SERIALID, имеющей максимум INVOICEDATE

То же самое можно сделать без ROW_NUMBER(), как показано ниже.

SELECT *
FROM SERVICETRANS ST
WHERE INVOICEDATE = (
        SELECT MAX(INVOICEDATE)
        FROM SERVICETRANS STI
        WHERE STI.SERIALID = ST.SERIALID
        )

Примечание : Приведенный выше запрос может вернуть несколько строк для одной SERIALID, если MAX(INVOICEDATE) совпадает для нескольких записей одного и того же SERIALID.

0 голосов
/ 16 февраля 2020

Многие базы данных поддерживают LEAST() / GREATEST(). Возможно, самый эффективный метод, предполагающий отсутствие дубликатов:

WITH i AS (
      SELECT sat.INVOICEDATE, sat.SERIALID, sat.QTY
      FROM SALESTRANS sat
      UNION ALL
      SELECT set.INVOICEDATE, set.SERIALID, set.QTY
      FROM SERVICETRANS sat
     )
SELECT i.*
FROM (SELECT i.*,
             ROW_NUMBER() OVER (PARTITION BY SERIALID ORDER BY INVOICEDATE DESC) as seqnum
      FROM i
     ) i
WHERE seqnum = 1;

Обратите внимание, что если в одну и ту же дату есть два счета, это произвольно возвращает один из них. Используйте RANK(), если хотите оба.

Обратите внимание, что здесь используется UNION ALL, а не UNION. UNION накладные расходы на удаление дубликатов. Это не кажется полезным для такого запроса.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...