Я пытаюсь разобраться в этой головоломке уже более нескольких часов, таблица выглядит так:
table:
n1 n2 r
---------
A D G
B D G
C D G
A E G
B E G
C E G
A F G
B F G
C F G
И ожидаемые результаты:
result:
n1 n2 r
---------
A D G
B E G
C F G
Я пытался объединиться, присоединиться, но не недоставало. Вот код, но он дает мне совершенно разные результаты:
select * from table t1
join table t2
on t2.r = t1.r
and t1.n1 > t2.n1
В общем случае n1 и n2 должны быть сгруппированы по r, а повторения в n2 должны быть удалены.
Следующие пользовательские переменные используют для имитации анализируемого числа строк для присвоения номера строки каждому уникальному значению в столбцах n1 и n2. Это значение в дополнение к R
используется для объединения двух наборов Der_N1 и Der_N2, чтобы мы могли генерировать набор результатов, оценивая каждое значение в N1 для каждого значения в N2, гарантируя, что каждое значение используется только один раз для каждого значения R.
SELECT N1, N2, Der_N1.R
FROM (SELECT Distinct N1, R, @N1RN:=@N1RN+1 RN
FROM (SELECT distinct N1, R
FROM SO48873185) X
CROSS JOIN (SELECT @N1RN:=0) Z) Der_N1
INNER JOIN (SELECT Distinct N2, R, @N2RN:=@N2RN+1 RN
FROM (SELECT distinct N2, R
FROM SO48873185) X
CROSS JOIN (SELECT @N2RN:=0) Z) Der_N2
on Der_N1.RN = Der_N2.RN
and Der_N1.R = Der_N2.R
В результате чего:
+----+----+----+---+
| | N1 | N2 | R |
+----+----+----+---+
| 1 | A | D | G |
| 2 | B | E | G |
| 3 | C | F | G |
+----+----+----+---+
Предположение, являющееся наименьшим значением N1 (x), должно быть сопряжено с наименьшим значением N2 (y), а следующее низшее x (x + 1) должно быть сопряжено со следующим самым низким N2 (y + 1) в порядке возрастания и так далее.,
Включая R в объединение; Я считаю, что мы обрабатываем каждый набор, и никакая группировка не нужна.
Я не знаком с ними; и не уверены, какую версию MySQL им представили, но я считаю, что вам понадобится рекурсивное "CTE" (общее табличное выражение). Что-то вроде:
WITH RECURSIVE cte (n1, n2, r) AS
(
SELECT n1, n2, r FROM theTable ORDER BY n1, n2 ASC LIMIT 1
UNION ALL
SELECT n1, n2, r
FROM theTable AS t
WHERE NOT EXISTS (
SELECT 1
FROM cte AS c
WHERE c.n1 IN (t.n1, t.n2) OR c.n2 IN (t.n1, t.n2)
)
ORDER BY n1, n2 ASC
LIMIT 1
)
SELECT * FROM cte;
Возможно, вам придется столкнуться с LIMIT на этой второй части; если он работает без изменений, я действительно был бы немного удивлен.