好吧,这是我解决问题的方法。
以下是节点和边表的草图:
[nodes]
node : varchar(xx)
[edges]
outputNode : varchar(xx)
inputNode : varchar(xx)
假设您的数据库支持CTE,那么这样的查询结构将把关系组合在一起并连接结果:
/* pair output nodes with a topic, assigned sequentially */
WITH OutputTopics(node, topicNumber) AS (
SELECT outputNode, ROW_NUMBER() (ORDER BY outputNode) AS topicNumber
FROM
(SELECT DISTINCT outputNode FROM edges) AS outputNodes
),
/* pair input nodes to the topic of associated output nodes */
InputTopicNumbers(inputNode, topicNumber) AS (
SELECT edges.inputNode, ot.topicNumber FROM edges INNER JOIN
OutputTopics AS ot ON ot.node=edges.outputNode
),
/* Recursive CTE to concat all topics together */
InputTopics(inputNode, topics, topicNumber) AS (
/* The seed for the recursion - all input nodes */
SELECT inputNode, CAST ('' AS nvarchar(max)), 0 /* max topic handled for node */
FROM InputTopicNumbers
GROUP BY inputNode
UNION ALL /* Add topics that are greater than those processed */
/* recursively concat topic numbers in ascending order */
SELECT i.inputNode, CONCAT(c.topics, ' --input-topic=T',i.topicNumber), i.topicNumber
FROM InputTopics AS c
INNER JOIN InputTopicNumbers i ON i.inputNode=c.inputNode
WHERE i.topicNumber > c.topicNumber
),
/* Bring it all together - append each node with '.exe',
list the output topic, if present
Use the recursive CTE to concat all inputTopics */
NodeCommands(node, exe, input, output) AS (
SELECT nodes.node,
CONCAT(nodes.node,'.exe'),
CONCAT(' --output_topic=T',ot.topicNumber), /* NULL if no output node */
it.topics
FROM nodes
LEFT OUTER JOIN OutputTopics AS ot ON ot.node=nodes.node
LEFT OUTER JOIN InputTopics AS it ON it.inputNode=nodes.node
)
/* finally our top-level query concatenates the parts to
arrive at a single command line */
SELECT CONCAT(
exe,
ISNULL(input, ''),
ISNULL(output, ''))
FROM NodeCommands ORDER BY node
我正在做这件事,所以肯定有一些语法错误。我希望这些评论能解释其意图。