1

我有这张桌子

CREATE TABLE IF NOT EXISTS `branch` (
  `id` int(11) NOT NULL AUTO_INCREMENT,  
  `studcount` int(11) DEFAULT NULL,
  `username` varchar(64) NOT NULL,
  `branch_fk` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKADAF25A2A445F1AF` (`branch_fk`),
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=14 ;
ALTER TABLE `branch`
  ADD CONSTRAINT `FKADAF25A24CEE7BFF` FOREIGN KEY (`login_fk`) REFERENCES `login` (`id`);

如您所见,每个表都有一个指向其他分支行的外键(自我关系)我想要一个使用 HQL(首选 HQL)的查询从我那里获取用户名(或 ID)并返回一个List<String>(对于用户名)或List<Integer>(对于id) 那是我所有子分支的列表;

让我在示例中展示

id         studentcount            username            branch_fk
1          312                     user01                NULL
2          111                     user02                1
3          432                     user03                1
4          543                     user04                2
5          433                     user05                3
6          312                     user06                5
7          312                     user06                2
8          312                     user06                7

当我调用 GetSubBranch(3) 时,我想返回:

5, 6

当调用 GetSubBranch(2) 时,我想返回:

4, 7, 8
4

2 回答 2

1

我相信没有可移植的 SQL 来做到这一点。更何况,我认为几大数据库的SQL都无法表达这一点。

因此,此功能不是您可以在 HQL 中执行的部分功能。对不起 :-(

我读了一些方法。其中大多数涉及根据级别数(预先固定?多少?),记录数(数亿?数百万?)等进行权衡:

  1. 自己进行递归查询,每次都降级(使用 a in(ids)),直到某个级别为空。
  2. 使用固定数量的左连接进行查询(您的深度需要提前知道;或者如果需要,您可能需要重复查询以查找其余记录,请参见第 1 点)。
  3. 在某处提供非规范化信息:它可能是索引的非规范化表复制。但我更喜欢缓存的内存副本,它可能仅在一个请求中完全填充,并被更新或失效……取决于您的其他要求,如表大小、最大深度、写入频率等)。
于 2009-08-02T14:42:55.723 回答
1

可以看看“嵌套集”。查询变成了“在 :L 和 :R 之间”的问题。但是拓扑/分层排序丢失了(与递归/分层查询相比)。然后插入新项目非常昂贵,因为它需要更新几行(如果不是全部)...

于 2011-10-26T17:28:27.223 回答