Рекурсивный запрос с использованием HQL - PullRequest
1 голос
/ 02 августа 2009

У меня есть эта таблица

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`);

как видите, у каждой таблицы есть внешний ключ, указывающий на другую ветку Row (self Relation) Я хочу, чтобы запрос с использованием HQL (предпочтительнее HQL) получал от меня имя пользователя (или идентификатор) и возвращал List<String> (для имени пользователя) или List<Integer> (для идентификатора), который представлял собой список всех моих подразделов;

позвольте мне показать в Примере

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

Ответы [ 2 ]

1 голос
/ 26 октября 2011

Можно взглянуть на «вложенные множества». Запрос становится вопросом «между: L и: R». Но топологический / иерархический вид теряется (по сравнению с рекурсивными / иерархическими запросами). Вставка новых элементов довольно затратна, поскольку требует обновления нескольких, если не всех строк ...

1 голос
/ 02 августа 2009

Я считаю, что для этого нет переносимого SQL. Более того, я думаю, что SQL нескольких крупных баз данных не может выразить это.

Следовательно, эта возможность не является частью того, что вы можете сделать в HQL. Извините: - (

Я прочитал несколько способов пойти. Большинство из них включают компромиссы в зависимости от количества уровней (фиксированных заранее? Сколько?), Количества записей (сотни? Миллионы?) И т. Д .:

  1. Выполняйте рекурсивные запросы самостоятельно, выравнивая каждый раз (с помощью in(ids)), пока какой-то уровень не станет пустым.
  2. Выполните запрос с фиксированным числом левых соединений (ваша глубина должна быть известна заранее; или вам может потребоваться повторить запрос, чтобы найти остальные записи, если необходимо, см. Пункт 1).
  3. Иметь где-нибудь денормализованную информацию: это может быть денормализованное копирование индексов из таблицы. Но я бы предпочел кешированную копию в памяти, которая может быть полностью заполнена только одним запросом и может быть обновлена ​​или аннулирована ... в зависимости от ваших других реквизитов, таких как размер таблицы, максимальная глубина, частота записи и т. Д.).
...