Я пытаюсь написать запрос, который подсчитывает количество двунаправленных (сильных) соединений между пользователями, которые представляют узлы на графике.
Для проверки запроса я создал следующий образец
, который хранится в таблице month_connections_test:
calling_party, called_party, link_strength
z1 z2 1,0000000
z1 z3 1,0000000
z3 z1 1,0000000
z1 z4 1,0000000
z1 z5 1,0000000
z5 z1 1,0000000
z2 z4 1,0000000
z2 z5 1,0000000
z5 z2 1,0000000
z2 z7 1,0000000
z7 z2 1,0000000
z4 z7 1,0000000
z7 z4 1,0000000
z2 z1 1,0000000
Следующий запрос возвращает 2 для сильных соединений между z1 и z2 вместо 1:
SELECT user1, user2, 0 AS calling_calling, 0 AS calling_called, 0 AS called_calling, 0 AS called_called, COUNT(*) AS both_directions
FROM (SELECT monthly_connections_test.calling_party AS user1, monthly_connections_test_1.calling_party AS user2
FROM monthly_connections_test INNER JOIN
monthly_connections_test AS monthly_connections_test_1 ON
monthly_connections_test.called_party = monthly_connections_test_1.called_party AND
monthly_connections_test.calling_party < monthly_connections_test_1.calling_party) t1
INNER JOIN monthly_connections_test AS monthly_connections_test_2 ON
t1.user2 = monthly_connections_test_2.called_party
AND t1.user2 < monthly_connections_test_2.calling_party
GROUP BY t1.user1, t1.user2
Результаты в следующем примере:
z1 z2 0 0 0 0 2
z2 z3 0 0 0 0 3
z2 z4 0 0 0 0 1
z1 z5 0 0 0 0 3
z2 z5 0 0 0 0 3
z3 z5 0 0 0 0 2
z1 z7 0 0 0 0 4
z2 z7 0 0 0 0 1
z5 z7 0 0 0 0 1
Кто-нибудь знает, как изменить запрос, чтобы он возвращал количество общих соседей, которые связаны в обоих направлениях (в этом примере правильное значение для z1, z2 равно 1, так как z5 связан с обоими z1 и z2 в обоих направления)?
Проблема, я думаю, в части
INNER JOIN monthly_connections_test AS monthly_connections_test_2 ON
t1.user2 = monthly_connections_test_2.called_party
AND t1.user2 < monthly_connections_test_2.calling_party
Правильный результат должен быть следующим:
z1 z2 0 0 0 0 1
z2 z3 0 0 0 0 1
z2 z4 0 0 0 0 1
z1 z5 0 0 0 0 1
z2 z5 0 0 0 0 1
z3 z5 0 0 0 0 1
z1 z7 0 0 0 0 1
z2 z7 0 0 0 0 0
z5 z7 0 0 0 0 1
Условие соединения должно быть сформулировано таким образом, чтобы каждое соединение подсчитывалось только один раз (ранее подключенные соединения должны быть исключены на этом этапе), но не нашли решения.
P.S. Поскольку исходная таблица состоит из 24M записей, запрос должен быть написан таким образом, чтобы он возвращал результаты в приемлемом количестве времени. Попытка сначала написать запрос с несколькими вариантами выбора заняла слишком много времени.