У меня есть таблица (например, с именем Источник), например:
-------------
|Name|ID|...|
-------------
|A |1 |...|
|A |2 |...|
|A |3 |...|
|B |1 |...|
|B |2 |...|
|C |1 |...|
-------------
таким образом, каждое Имя может иметь несколько записей, каждая из которых имеет увеличивающийся ID (который, в свою очередь, разделен по Имени, как вы, вероятно, уже поняли) .
Теперь у меня есть другая таблица (называемая Dest), в которую я загружаю таблицу Source, например. ежедневные партии. Однако я хочу загрузить дельту только из Source, поэтому, если моя таблица Dest выглядит так:
-------------
|Name|ID|...|
-------------
|A |1 |...|
|A |2 |...|
|B |1 |...|
-------------
Я только хочу скопировать разницу из Source в Dest , которая будет следующей:
-------------
|Name|ID|...|
-------------
|A |3 |...|
|B |2 |...|
|C |1 |...|
-------------
По другим причинам я не могу использовать для этого отметку времени или минус, поэтому единственный способ найти разницу — получить MAX(ID) для каждого Имени и получить только записи > MAX(ID) для каждого Имени.
Самая быстрая реализация — через подзапрос, который подготавливает все MAX(ID) для каждого Name и использует его для устранения меньших ID. :
SELECT s.* FROM Source s
LEFT JOIN (
SELECT d.NAME, MAX(d.ID) AS MAX_ID
FROM Dest d
GROUP BY d.NAME) n
ON s.NAME = n.NAME
WHERE s.ID > COALESCE(n.MAX_ID,0)
Однако, поскольку в таблицах много записей, я считаю, что это будет не очень эффективно, если только Hive не оптимизирует его достаточно автоматически, в чем я не уверен.
Я надеялся сделать что-то вроде этого:
SELECT s.* FROM Source s
WHERE s.ID > (SELECT COALESCE(MAX(d.ID),0)
FROM Dest d
WHERE d.NAME = s.NAME)
Таким образом, я бы не вычислял MAX(ID) для всех записей, а вычислял бы его только для текущего Имени. Но это, по-видимому, невозможно в Hive.
Итак, мой вопрос: как лучше всего реализовать обнаружение дельты в Hive?