单向连接和“n度分离”在 MySQL 中?

发布于 2024-11-08 01:04:32 字数 243 浏览 0 评论 0原文

我有一个具有整数 ID 的实体表,我们将其称为实体。在另一个表中,我通过“从”、“到”列以及它们之间的关系类型(我们将此表称为“关系”)来在这些实体之间建立单向关系。实体可能是“双向”的,具有两个相应的单向关系,并且整体事物是一个图形或网络。

我正在编写一个例程,我可以向它传递一个实体 ID 以及要进行的分离度,然后它返回所传递 ID 的许多关系中的每个实体 ID。我不知道如何编写这个例程。这种迭代的性质超出了我对存储过程的经验。有任何线索如何开始吗?

I have a table of entities with integer IDs, let's call it Entities. In another table, I have one way relationships between these entities by having a column for "From", "To" and what kind of relationship they have (let's call this table Relationships). Entities might be "two way" by having two corresponding one way relationships and the overall thing is a graph or web.

I'm looking to write a routine where I can pass it an Entity ID and how many degrees of separation to go and it returns every entity ID within that many relationships of the passed ID. I have no idea how to write this routine. The iterative nature of this is beyond my experience with stored procedures. Any clues how to start this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森林散布 2024-11-15 01:04:32

对于具有 from_id 和 to_id 列的表关系

DROP PROCEDURE IF EXISTS find_relationships;
DELIMITER $

CREATE PROCEDURE find_relationships( start_id int(11), level int(11) )
BEGIN
  DECLARE found INT(11) DEFAULT 1;
  DROP TABLE IF EXISTS related_entities;
  CREATE TABLE related_entities (id int(11) PRIMARY KEY) ENGINE=HEAP;
  INSERT INTO related_entities VALUES ( start_id );
  WHILE found > 0 AND level > 0 DO
    INSERT IGNORE INTO related_entities
      SELECT DISTINCT from_id FROM relationships r
      JOIN related_entities rf ON r.to_id = rf.id 
      UNION 
      SELECT DISTINCT to_id FROM relationships r
      JOIN related_entities rf ON r.from_id = rf.id;
    SET found = ROW_COUNT();
    SET level = level - 1;
  END WHILE;
  SELECT * FROM related_entities;
  DROP TABLE related_entities;
END;
$
DELIMITER ;

应该适用于任何图形,查找以级别给出的距离内的所有连接节点。

call find_relationships( 5, 2 );

For a table relationships with columns from_id and to_id

DROP PROCEDURE IF EXISTS find_relationships;
DELIMITER $

CREATE PROCEDURE find_relationships( start_id int(11), level int(11) )
BEGIN
  DECLARE found INT(11) DEFAULT 1;
  DROP TABLE IF EXISTS related_entities;
  CREATE TABLE related_entities (id int(11) PRIMARY KEY) ENGINE=HEAP;
  INSERT INTO related_entities VALUES ( start_id );
  WHILE found > 0 AND level > 0 DO
    INSERT IGNORE INTO related_entities
      SELECT DISTINCT from_id FROM relationships r
      JOIN related_entities rf ON r.to_id = rf.id 
      UNION 
      SELECT DISTINCT to_id FROM relationships r
      JOIN related_entities rf ON r.from_id = rf.id;
    SET found = ROW_COUNT();
    SET level = level - 1;
  END WHILE;
  SELECT * FROM related_entities;
  DROP TABLE related_entities;
END;
$
DELIMITER ;

Should work for any graph, finding all connected nodes within distance given as level.

call find_relationships( 5, 2 );
夏末 2024-11-15 01:04:32

MySQL 中没有 with 语句,因此您需要一个临时表。伪代码:

drop table if exists tmp_nodes;

create temporary table tmp_nodes as
select :id as id;

while :depth++ < :max_depth
  insert into tmp_nodes
  select links.id
  from links
  join tmp_nodes as nodes on nodes.id = links.parent_id
  left join tmp_nodes as cycle on cycle.id = links.id
  where cycle.id is null;

select id from tmp_nodes optionally where id <> :id;

看起来 piotrm 已经为您编写了所需的函数。

There are no with statements in MySQL, so you'll need a temporary table. Pseudo-code:

drop table if exists tmp_nodes;

create temporary table tmp_nodes as
select :id as id;

while :depth++ < :max_depth
  insert into tmp_nodes
  select links.id
  from links
  join tmp_nodes as nodes on nodes.id = links.parent_id
  left join tmp_nodes as cycle on cycle.id = links.id
  where cycle.id is null;

select id from tmp_nodes optionally where id <> :id;

Looks like piotrm wrote the needed function for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文