2016-04-30 6 views
1

Как найти max из hierarchyid type column?Найти Max Hierarchyid в SQL Server

для например:

name | user_hierarchyid 
------------------------- 
Craig |/
Steve | /1/ 
John | /1/1/ 
Matt | /1/1/1/ 
Sam | /2/ 
Chris | /2/2/ 

Я попытался с помощью max(user_hierarchyid) но он возвращает /2/2/, но я хочу, чтобы получить максимум колонки иерархически т.е. /1/1/1/

Заранее спасибо.

+0

как heirrachy i s рассчитывается – TheGameiswar

+1

@TheGameiswar: hierarchyid рассчитывается вручную, в зависимости от их размещения. –

+0

Технически, '/ 1/1/1 /' * * - это иерархический максимум. Поскольку вы, по-видимому, хотите использовать другое определение «* иерархического максимума *», чем стандарт, вам нужно будет рассказать нам, каково ваше определение. – RBarryYoung

ответ

1

вы могли бы сделать что-то вроде ниже

with cte 
as 
(
select name,user_hier_id,replace(user_hierarchyid,'/','') as rplcd 
from table 
) 
select max(rplcd) from cte 
+0

Что делать, если есть значение типа '/ 10/11 /', и оно будет больше, чем '/ 1/1/2 /'? – gofr1

3

Вы можете использовать GetLevel(), чтобы получить уровень и TOP 1 WITH TIES, чтобы получить "максимальное" значение (глубочайшее):

SELECT TOP 1 WITH TIES * 
FROM mytable 
ORDER BY user_hierarchyid.GetLevel() DESC; 

LiveDemo

Выход:

╔══════╦══════════════════╗ 
║ name ║ user_hierarchyid ║ 
╠══════╬══════════════════╣ 
║ Matt ║ /1/1/1/   ║ 
╚══════╩══════════════════╝ 

В качестве альтернативы с помощью RANK():

SELECT * 
FROM (SELECT *, RANK() OVER(ORDER BY user_hierarchyid.GetLevel() DESC) AS rnk 
     FROM mytable) AS s 
WHERE rnk = 1; 

LiveDemo2

+0

Если я вставляю еще одну строку с user_hierarchyid как '/ 1/1/2 /', оба запроса возвращают '/ 1/1/1 /' и '/ 1/1/2 /'. Здесь я получаю user_hierarchyid как '/ 1/1/2 /', поскольку он является максимальным по иерархии. –

+0

@PankajJawale Пожалуйста, определите 'максимальную иерархию', потому что сначала я понимаю ее как« самую глубокую ». Что делать, если есть '/ 1/1/1' и'/1/2/1'? – lad2025

0
;WITH cte AS (
SELECT name, CAST(user_hierarchyid as hierarchyid) as user_hierarchyid 
FROM (VALUES 
('Craig', '/'), 
('Steve', '/1/'), 
('John', '/1/1/'), 
('Matt', '/1/1/1/'), 
('Sam', '/2/'), 
('Chris', '/2/2/') 
) as t(name, user_hierarchyid) 
) 

SELECT TOP 1 
     name, 
     CAST(user_hierarchyid as nvarchar(20)) as user_hierarchyid 
FROM (
    SELECT *, 
      user_hierarchyid.GetAncestor(CASE WHEN user_hierarchyid.GetLevel() > 0 THEN user_hierarchyid.GetLevel()-1 ELSE user_hierarchyid.GetLevel() END) as ga, 
      user_hierarchyid.GetLevel() as gl 
    FROM cte 
    ) as t 
ORDER BY Rank() OVER (PARTITION BY ga ORDER BY gl,user_hierarchyid) desc, ga DESC 

Выход:

name user_hierarchyid 
----- ----------------- 
Matt /1/1/1/ 

(1 row(s) affected) 

Если добавить строку ('Dave', '/1/1/2/'),, то выход будет Dave /1/1/2/

Если добавить строку ('Tony', '/2/2/1/'),, то выход будет Dave /1/1/2/

Если добавить ряд ('Ann', '/2/2/2/'), то выход будет Ann /2/2/2/

Если вы добавляете строка ('Vic', '/1/1/1/1/'),, тогда выход будет Vic /1/1/1/1/

Смежные вопросы