Мне нужно подсчитать края между соседями узлов в графе в SQL Server, тогда как у меня есть таблицы как GraphNodes
и GraphEdges
. Структура таблиц доступна в previous questionПередача параметров на запрос в SQL Server
, относящиеся к предыдущему вопросу, здесь есть аспект вопроса отличается как:
я должен выполнить следующие шаги, чтобы выполнить задачу, т.е.
взять узел говорят V от
GraphNodes
должны иметь список
DISTINCT
соседей для V (например, в TABLE переменная SQL)- чека (COUNT DISTINCT) связь между соседями V в
GraphEdges
- выхода В с отчетливыми связями между соседями
запросом у меня для одного узла работает нормально, т.е.
SELECT GN.id, COUNT(DISTINCT(CONCAT(GE.Source_Node,'-', GE.Target_Node))) AS NeighborLinks
FROM GraphEdges GE
JOIN GraphNodes GN ON GN.id = 512
WHERE Source_Node IN (SELECT DISTINCT Target_Node FROM GraphEdges WHERE Source_Node = 512
UNION ALL
SELECT DISTINCT Source_Node FROM GraphEdges WHERE Target_Node = 512
)
AND Target_Node IN (SELECT DISTINCT Target_Node FROM GraphEdges WHERE Source_Node = 512
UNION ALL
SELECT DISTINCT Source_Node FROM GraphEdges WHERE Target_Node = 512
)
GROUP BY GN.id
Я взял id = 512 в качестве образца, где находится id
в GraphNodes
. Этот запрос выводит как:
+-------+-----------------+
| id | NeighborLinks |
+-------+-----------------+
| 512 | 6 |
+-------+-----------------+
Причина использования UNION ALL
в пункте WHERE
является то, что id
т.е. 512
существует в обеих колонках т.е. Source_Node
и Target_Node
, а также, так что должны выбрать DISTINCT соседи из обеих колонок необходимо. Более того, используя тот же список для GE.Source_Node
и GE.Target_Node
, потому что нужно проверять ссылки только между соседями V т. Е. 512
.
Вопрос заключается в том, как использовать то, что я думаю, что переменная TABLE или любой другой способ, чтобы разобраться в этой проблеме предоставления длинного списка значений вместо 512
Я пришел к этому решению в отношении переменной таблицы, но получил сообщение об ошибке с помощью табличные переменные внутри запроса как:
Try 1
DECLARE @ID TABLE(id INT)
DECLARE @S_Neighbor TABLE (id INT)
DECLARE @T_Neighbor TABLE (id INT)
INSERT INTO @ID SELECT id FROM GraphNodes
INSERT INTO @S_Neighbor SELECT DISTINCT Source_Node
FROM GraphEdges
WHERE Target_Node IN (SELECT id FROM @ID)
--UNION ALL
INSERT INTO @T_Neighbor SELECT DISTINCT Target_Node
FROM GraphEdges
WHERE Source_Node IN (SELECT id FROM @ID)
SELECT GN.id,COUNT(DISTINCT(CONCAT(GE.Source_Node,'-', GE.Target_Node))) AS Mutual_Links
FROM GraphEdges GE
JOIN GraphNodes GN ON GN.id = @ID
WHERE Source_Node IN (SELECT DISTINCT Target_Node
FROM GraphEdges
WHERE Source_Node IN @T_Neighbor
UNION ALL
SELECT DISTINCT Source_Node
FROM GraphEdges
WHERE Target_Node IN @S_Neighbor)
AND Target_Node IN (SELECT DISTINCT Target_Node
FROM GraphEdges
WHERE Source_Node IN @S_Neighbor
UNION ALL
SELECT DISTINCT Source_Node
FROM GraphEdges
WHERE Target_Node IN @T_Neighbor)
GROUP BY GN.id
Я также попытался это:
Попробуйте 2
DECLARE @ID_COUNTER INT
DECLARE @MAX_ID INT
SET @ID_COUNTER = 1
SET @MAX_ID = 148410
WHILE @ID_COUNTER <= @MAX_ID
BEGIN
(
SELECT GN.id,
COUNT(DISTINCT(CONCAT(GE.Source_Node,'-', GE.Target_Node))) AS Mutual_Links
FROM GraphEdges GE
JOIN GraphNodes GN ON GN.id = @ID_COUNTER
WHERE Source_Node IN (SELECT DISTINCT Target_Node
FROM GraphEdges WHERE Source_Node = @ID_COUNTER
UNION ALL
SELECT DISTINCT Source_Node
FROM GraphEdges WHERE Target_Node = @ID_COUNTER
)
AND Target_Node IN (SELECT DISTINCT Target_Node
FROM GraphEdges WHERE Source_Node = @ID_COUNTER
UNION ALL
SELECT DISTINCT Source_Node
FROM GraphEdges WHERE Target_Node = @ID_COUNTER
)
GROUP BY GN.id
)
SET @ID_COUNTER += 1
END
Я использовал @MAX_ID = 3, и для возврата результата потребовалось 56 секунд, тогда как @MAX_ID изначально = 148410.Хотя возвращаемые значения NeighborLinks
правильны, но результат, показанный в трех отдельных окнах для как:
id NeighborLinks
1 53
id NeighborLinks
2 318
id NeighborLinks
3 297
... Вы написали все это, чтобы спросить, как передать список значений int в качестве параметра? –
Вы уже предлагаете переменную таблицы самостоятельно. Что удерживает вас от использования переменных таблицы? Альтернативой будет использование временной таблицы для хранения идентификатора. –
@IvanStarostin Не все да, но это проблема с двумя краями, одна из них заключается в том, как сохранять и передавать значения int в качестве параметра повторно, а другое - как присоединяться к одному столбцу дважды – maliks