Функция плотного ранга

#sql #sql-server

#sql #sql-сервер

Вопрос:

 select node, parent, dense_rank() over (partition by parent order by node)
from tree
  

Когда я запускаю этот запрос, я получаю

 node parent (No column name)
1    0      1
2    1      1
3    1      2
4    2      1
5    2      2 
6    3      1 
7    3      2
  

Где я ожидал следующего результата

 node    parent  (No column name)
1       0       1
2       1       2
3       1       2
4       2       3
5       2       3
6       3       4
7       3       4
  

Почему функция плотного ранга не группируется по родительскому принципу?

Комментарии:

1. Ваш ожидаемый результат — нет dense_rank . Ваш результат parent 1 .

Ответ №1:

Попробуйте это:

   select node,parent,dense_rank() over (order by parent) from tree
  

Вам не нужно использовать раздел в dense_rank() порядке just order by parent, он выполнит эту работу.

Комментарии:

1. вы должны использовать parent в предложении order by .

2. ага .. 1.. Я также опубликовал то же самое .. 🙂

3. сэр, я уже получаю результат, но почему раздел меняет мой результат

4. @ARJUN Когда вы разбиваете его по родительскому элементу, он сбрасывает значение РАНГА для каждого родительского элемента. т.е. Для каждого родительского значения РАНГ будет начинаться с 1. Таким образом, каждое новое родительское значение у вас будет 1, а затем, если у этих родителей будет больше записей, РАНГ будет увеличиваться один за другим.

Ответ №2:

Используйте ее без РАЗДЕЛЕНИЯ:

 ;WITH tree AS (
SELECT *
FROM (VALUES
(1,0),(2, 1),(3, 1),(4, 2),(5, 2), (6, 3), (7, 3)
) as t(node, parent)
)

select  node,
        parent,
        dense_rank() over (order by parent) 
from tree
  

Вывод:

 node    parent  (No column name)
1       0       1
3       1       2
2       1       2
5       2       3
4       2       3
7       3       4
6       3       4
  

Примечание: PARTITION делит результирующий набор, созданный FROM предложением, на разделы, к которым DENSE_RANK применяется функция. Таким образом, результирующий набор разбивается на разделы parent и упорядочивается по node . И вам нужно разбиение по всем строкам, поэтому вам не нужно разбиение ни по одному столбцу.

Комментарии:

1. что произойдет, если я использую раздел

Ответ №3:

используйте приведенный ниже сценарий.

   select node,parent,dense_rank() over (order by parent) from tree
  

Пример вывода :

введите описание изображения здесь

Комментарии:

1. если вы используете раздел dense_rank (), он будет подсчитываться на основе разделенного столбца, что означает, что при любом изменении значения разделенного столбца счетчик будет сброшен до единицы.

2. Должно быть over(order by parent, node) , да?

Ответ №4:

Вам не нужно разделять по предложению

 declare @t table(node int, parent int)
insert into @t 
select 1,0 union all
select 2,1 union all
select 3,1 union all
select 4,2 union all
select 5,2 union all
select 6,3 union all
select 7,3 

select node,parent,dense_rank() over (order by parent)  from @t
  

Ответ №5:

То, что вы, похоже, хотите, основываясь на ожиданиях, — это (плотное) ранжирование на основе родительских узлов.

Что вам нужно сделать для достижения этой цели, это просто порядок родительского элемента. Если вы разбиваете по родительскому элементу, вы получаете ранг узла внутри каждого родительского элемента.

 WITH
-- CTE to generate the same data
tree AS (
   SELECT 1 AS node, 0 AS parent
   UNION ALL SELECT 2, 1
   UNION ALL SELECT 3, 1
   UNION ALL SELECT 4, 2
   UNION ALL SELECT 5, 2
   UNION ALL SELECT 6, 3
   UNION ALL SELECT 7, 3
)
SELECT
   node,
   parent,
   DENSE_RANK() OVER (ORDER BY parent) AS your_rank
FROM tree;
  

Как говорится в документации, разделение…

[d] разбивает результирующий набор, созданный предложением FROM, на разделы, к которым применяется функция DENSE_RANK .

Итак, если вы разделяете по родительскому элементу, вы говорите SQL Server создавать небольшие группы узлов для каждого родительского элемента, а затем вычислять ранг внутри этой группы, начиная с 1 для каждой группы.