5

这是我的数据的样子:

| col1 | col2 | denserank | whatiwant |
|------|------|-----------|-----------|
| 1    | 1    | 1         | 1         |
| 2    | 1    | 1         | 1         |
| 3    | 2    | 2         | 2         |
| 4    | 2    | 2         | 2         |
| 5    | 1    | 1         | 3         |
| 6    | 2    | 2         | 4         |
| 7    | 2    | 2         | 4         |
| 8    | 3    | 3         | 5         |

这是我到目前为止的查询:

SELECT col1, col2, DENSE_RANK() OVER (ORDER BY COL2) AS [denserank]
FROM [table1]
ORDER BY [col1] asc

我想要实现的是,每次 col2 的值发生变化时,我的 denserank 列都会增加(即使值本身被重用)。我实际上不能按我有 denserank 的列排序,所以这行不通)。whatiwant有关示例,请参见列。

有什么办法可以做到这一点DENSE_RANK()吗?还是有替代方案?

4

4 回答 4

4

我会用这样的递归 cte 来做到这一点:

declare @Dept table (col1 integer, col2 integer)

insert into @Dept values(1, 1),(2, 1),(3, 2),(4, 2),(5, 1),(6, 2),(7, 2),(8, 3)

;with a as (
select col1, col2, 
ROW_NUMBER() over (order by col1) as rn
from @Dept),
s as 
(select col1, col2, rn, 1 as dr from a where rn=1
union all
select a.col1, a.col2, a.rn, case when a.col2=s.col2 then s.dr else s.dr+1 end as dr 
from a inner join s on a.rn=s.rn+1)
col1, col2, dr from s

result:

col1        col2        dr
----------- ----------- -----------
1           1           1
2           1           1
3           2           2
4           2           2
5           1           3
6           2           4
7           2           4
8           3           5

只有在您的 col1 值不连续时才需要 ROW_NUMBER。如果是,您可以立即使用递归 cte

于 2017-01-31T04:55:24.167 回答
3

这是使用SUM OVER(Order by)窗口聚合函数的一种方法

SELECT col1,Col2,
       Sum(CASE WHEN a.prev_val = a.col2 THEN 0 ELSE 1 END) OVER(ORDER BY col1) AS whatiwant 
FROM   (SELECT col1,
               col2,
               Lag(col2, 1)OVER(ORDER BY col1) AS prev_val
        FROM   Yourtable) a
ORDER  BY col1; 

这个怎么运作:

LAG窗口函数用于查找按col2顺序排列的每一行的前一个col1

SUM OVER(Order by)col2仅当先前不等于当前时才会增加数字col2

于 2017-01-31T06:40:00.443 回答
3

尝试使用窗口函数:

with t(col1  ,col2) as (
select 1 , 1 union all  
select 2 , 1 union all  
select 3 , 2 union all  
select 4 , 2 union all  
select 5 , 1 union all  
select 6 , 2 union all  
select 7 , 2 union all  
select 8 , 3
)
select t.col1,
    t.col2,
    sum(x) over (
        order by col1
        ) whatyouwant
from (
    select t.*,
        case 
            when col2 = lag(col2) over (
                    order by col1
                    )
                then 0
            else 1
            end x
    from t
    ) t
order by col1;

生产:

在此处输入图像描述

它执行单个表读取并按 col1 的递增顺序形成一组连续相等的 col2 值,然后在其上找到密集排名。

  • x: 如果前一行的 col2 与本行的 col2 相同(按递增顺序col1),则赋值为 0,否则为 1
  • whatyouwant:通过对最后一步中生成的值进行增量求和,按递增col2顺序创建相等值的组,这就是您的输出。col1x
于 2017-01-31T04:47:21.763 回答
1

我认为这在纯 SQL 中使用一些间隙和孤岛技巧是可能的,但阻力最小的路径可能是使用会话变量结合LAG()来跟踪计算的密集等级何时更改值。在下面的查询中,我@a用来跟踪密集等级的变化,当它变化时,这个变量加 1。

DECLARE @a int
SET @a = 1
SELECT t.col1,
       t.col2,
       t.denserank,
       @a = CASE WHEN LAG(t.denserank, 1, 1) OVER (ORDER BY t.col1) = t.denserank
                 THEN @a
                 ELSE @a+1 END AS [whatiwant]
FROM
(
    SELECT col1, col2, DENSE_RANK() OVER (ORDER BY COL2) AS [denserank]
    FROM [table1]
) t
ORDER BY t.col1
于 2017-01-31T04:45:38.980 回答