Вот мой тестовый пример
CREATE TABLE matches AS
SELECT 1 s, 2 d
UNION SELECT 1, 3 -- (1,2) preferred
UNION SELECT 2, 2 -- (1,2) preferred
UNION SELECT 2, 3
UNION SELECT 3, 3 -- (2,3) preferred
UNION SELECT 3, 4;
Я хочу отфильтровать эту таблицу и сохранить каждое значение s или d только один раз, задавая приоритеты наименьшим (s, d) парам. Результат должен быть (1,2),(2,3),(3,4)
. Как это сделать эффективно?
Я попробовал запрос ниже, но он работает только в том случае, если значения d, связанные с разными значениями s, не перекрываются
SELECT * FROM (
SELECT
*,
row_number() OVER (PARTITION BY s ORDER BY d) rs,
row_number() OVER (PARTITION BY d ORDER BY s) rd
FROM matches
) t
WHERE rd = rs;
Любая помощь будет очень высоко ценится.
Если я правильно интерпретирую ваши намерения, вы можете сделать это, скопировав таблицу в новую (возможно временную) таблицу с индексами UNIQUE на s
и d
и используя INSERT IGNORE
для копирования данных:
CREATE TABLE matches AS
SELECT 1 s, 2 d
UNION SELECT 1, 3 -- (1,2) preferred
UNION SELECT 2, 2 -- (1,2) preferred
UNION SELECT 2, 3
UNION SELECT 3, 3
UNION SELECT 3, 4;
CREATE TABLE matches2 (s INT, d INT);
ALTER TABLE matches2 ADD UNIQUE KEY (s), ADD UNIQUE KEY(d);
INSERT IGNORE INTO matches2
SELECT * FROM matches ORDER BY s, d;
SELECT * FROM matches2
Выход:
s d
1 2
2 3
3 4