Эту проблему можно решить, используя rowids для объединения результатов объединения.Оконные функции не нужны.(Спасибо xQbert за указание меня в этом направлении.)
Сначала мы сортируем две таблицы по v
, чтобы сделать таблицы со строками строк в подходящем порядке для объединения.
CREATE TEMPORARY TABLE Xv AS SELECT * FROM X ORDER BY v;
CREATE TEMPORARY TABLE Yv AS SELECT * FROM Y ORDER BY v;
Затем мы можем выбрать минимальный идентификатор строки для каждого значения v
, чтобы создать «zip-соединение» для этого значения, объединяя строки в ряд.
SELECT i, Yv.k, Xv.v
FROM Xv JOIN Yv USING (v)
JOIN (SELECT v, min(Xv.rowid) AS r FROM Xv GROUP BY v) AS xmin USING (v)
JOIN (SELECT v, min(Yv.rowid) AS r FROM Yv GROUP BY v) AS ymin
ON ymin.v = Xv.v AND Xv.rowid - xmin.r = Yv.rowid - ymin.r;
предложение Xv.rowid - min.x = Yv.rowid - min.y
- хитрость: оно выполняет попарное сопоставление строк с одинаковым значением v
, по существу выделяя одно другому.Результат:
i k v
---------- ---------- ----------
q 0 a
s 2 a
p 1 b
В таком случае просто использовать результат этого запроса в ОБНОВЛЕНИИ.
WITH changes AS (<the SELECT above>)
UPDATE X SET k = (SELECT k FROM changes WHERE i = X.i)
WHERE i IN (SELECT i FROM changes);
Временные таблицы могут быть ограничены общими значениями v
и, возможно, проиндексирован на v
, если запрос большой.
Я бы приветствовал уточнения (или ошибки!)