2015-09-19 2 views
0

У меня есть этот рекурсивный SQL запрос, где я получить иерархию идентификаторов каждого офиса (офис принадлежит к более высокому рангу должности и тому подобное) - вдохновленный @ leftclickben отвечают в How to do the Recursive SELECT query in MySQL?:Рекурсивный Dynamic Query

select @pv := o.office_id, o.display_name, (
         select concat(concat(group_concat(@pv := t.parent_office_id order by t.parent_office_id asc SEPARATOR '.'), '.'), t.office_id) pivot 
         from (select * from office order by (CASE WHEN parent_office_id < office_id THEN parent_office_id END) DESC, 
              (CASE WHEN parent_office_id > office_id THEN parent_office_id END) ASC) t 
               where t.office_id = @pv 
              ) 'hierarchy' 
from office o 
group by o.office_id 
order by o.office_id asc, o.parent_office_id desc 
; 

Для этот запрос для работы, он нуждается в перфективном потомстве или влиянии, которое должно быть проверено. Это свойство не проверено в моих данных, и поэтому мне пришлось воспользоваться выборочным заказом от в подзапросе.

Я получил очень обнадеживающие результаты (точность 80%), и мне было интересно, может ли кто-нибудь предложить больше методов для получения лучших результатов?

Примеры:

- for some office (ID = 97), its hierarchy is 1.2.4.14.97 (accurate value); 

- for another case (ID = 101), I get: 111.101 (broken hierarchy); 

В двух словах, все результаты должны начинаться с 1.

Хороший образец:

http://sqlfiddle.com/#!9/82f13/1

+1

Если вы отфильтровываете, где начинается список иерархии с 1, у вас есть правильные результаты? –

+0

В этом случае это обратная иерархия. Поэтому, когда я начинаю с 1, я должен получить 1 (фактический результат равен NULL). Если я начну с 2, я должен получить 1,2 и т. Д. ... –

+1

Что я имею в виду, имеет ли ваш набор результатов все правильные иерархии в дополнение к сломанным? Если это так, вы можете отфильтровать сломанные и сделать это. –

ответ

0

На основании предположения @Hart CO, я решена это с тремя запросами с двумя соединениями:

(select @pv := o.office_id, o.display_name, ifnull((
         select concat(concat(group_concat(@pv := t.parent_office_id order by t.parent_office_id asc SEPARATOR '.'), '.'), t.office_id) pivot 
         from (select * from office order by parent_office_id desc) t 
               where t.office_id = @pv 
              ), '1.') 'hierarchy' 
from office o 
where office_id not in (26, 27, 28, 29, 30, 32, 33, 34, 41, 57, 58, 59, 60, 61, 62, 63, 64, 73, 74, 75, 76, 77, 79, 82, 91, 96, 101, 102, 103, 104) 
group by o.office_id 
order by o.parent_office_id desc) 
union 
(

select @pv := o.office_id, o.display_name, (
         select concat(concat(group_concat(@pv := t.parent_office_id order by t.parent_office_id asc SEPARATOR '.'), '.'), t.office_id) pivot 
         from (select * from office order by parent_office_id DESC) t 
               where t.office_id = @pv 
              ) 'hierarchy' 
from office o 
where office_id in (26, 27, 28, 29, 30, 32, 33, 34, 41, 57, 58, 59, 60, 61, 62, 63, 64, 91, 96, 101, 102, 103, 104) 
group by o.office_id 
order by o.parent_office_id desc 
) 
union 
(select @pv := o.office_id, o.display_name, (
         select concat(concat(group_concat(@pv := t.parent_office_id order by (select parent_office_id from office where office_id = t.parent_office_id) asc SEPARATOR '.'), '.'), t.office_id) pivot 
         from (select * from office oo order by (select parent_office_id from office where office_id = oo.parent_office_id) deSC) t 
               where t.office_id = @pv 
              ) 'hierarchy' 
from office o 
where office_id in (73, 74, 75, 76, 77, 79, 82) 
group by o.office_id 
order by o.parent_office_id desc 
); 

Действительно, первый запрос был прямым: parent_id меньше.

Для второго запроса parent_id был больше на нижнем уровне.

Для третьего запроса parent_id родителя больше, поэтому я выбрал подзапрос в порядке по порядку для group_concat и подзапроса с псевдонимом t.

Я могу, наконец, двигаться вперед с помощью своего ETL.