2016-06-02 4 views
2

내 레코드에 대해 연속적인 Null 값의 순위를 지정하고 싶습니다. 모든 레코드는 1 등급이됩니다. 한 번만 나타나는 null 값의 경우 순위는 1이됩니다. 그러나 연속적으로 나타나는 null 값의 경우 순위는 첫 번째 레코드의 경우 1이되고 두 번째 레코드의 경우 2가됩니다 기록 등등. 여기 내 코드가있다.연속 Null 값의 순위를 지정하십시오.

CREATE TABLE #my_table 
(
    id BIGINT      IDENTITY PRIMARY KEY 
    ,fruit       varchar(100) 
); 

INSERT INTO #my_table 
      SELECT 'apple' 
UNION ALL SELECT 'apple' 
UNION ALL SELECT NULL 
UNION ALL SELECT 'pineapple' 
UNION ALL SELECT 'banana' 
UNION ALL SELECT NULL 
UNION ALL SELECT NULL 
UNION ALL SELECT 'orange' 

select * from #my_table 

의도 된 결과

+----+-----------+------+ 
| id | fruit  | rank | 
+----+-----------+------+ 
| 1 | apple  | 1 | 
| 2 | apple  | 1 | 
| 3 | NULL  | 1 | 
| 4 | pineapple | 1 | 
| 5 | banana | 1 | 
| 6 | NULL  | 1 | 
| 7 | NULL  | 2 | 
| 8 | orange | 1 | 
+----+-----------+------+ 

내가 그것을 어떻게 조회해야합니까?

도와주세요!

+0

SQL Server 버전? –

+0

안녕하세요! SQL 서버 2014 – eric

답변

1

당신은 연속 NULL 값의 그룹화를 얻기 위해 ROW_NUMBER의 차이를 사용할 수 있습니다 재귀를 사용하지 않는 솔루션에 따라

WITH Cte AS(
    SELECT *, 
     g = ROW_NUMBER() OVER(ORDER BY id) 
       - ROW_NUMBER() OVER(PARTITION BY fruit ORDER BY id) 
    FROM #my_table 
) 
SELECT 
    id, 
    fruit, 
    CASE 
     WHEN fruit IS NULL THEN ROW_NUMBER() OVER(PARTITION BY fruit, g ORDER BY id) 
     ELSE 1 
    END AS rank 
FROM Cte 
ORDER BY id; 

ONLINE DEMO

1
CREATE TABLE #my_table 
(
    id BIGINT      IDENTITY PRIMARY KEY 
    ,fruit       varchar(100) 
); 

INSERT INTO #my_table 
      SELECT 'apple' 
UNION ALL SELECT 'apple' 
UNION ALL SELECT NULL 
UNION ALL SELECT 'pineapple' 
UNION ALL SELECT 'banana' 
UNION ALL SELECT NULL 
UNION ALL SELECT NULL 
UNION ALL SELECT 'orange' 

; 
WITH REC_CTE (id,fruit,ranks) 
    AS (
     -- Anchor definition 
     SELECT id, 
       fruit, 
       1 as ranks 
     FROM #my_table 
     WHERE fruit is not null 

      -- Recursive definition 
     UNION ALL 
     SELECT son.id, 
       son.fruit, 
       case when son.fruit is null AND father.fruit is null then 
        father.ranks + 1 
        else 
        1 
       end as ranks 
     FROM #my_table son INNER JOIN 
       REC_CTE father 
     on son.id = father.id +1 
     WHERE son.fruit is null 
      --AND father.fruit is null 
    ) 

    SELECT * from REC_CTE order by id 

    DROP TABLE #my_table 
0

가 (32,767 수준으로 제한 = ~ 행은 솔루션에 따라 다릅니다.) 또한 두 개의 집계/순위 지정 기능 (SUMDENSE_RANK) 만 사용합니다 :

;WITH Base 
AS (
    SELECT *, IIF(fruit IS NULL, SUM(IIF(fruit IS NOT NULL, 1, 0)) OVER(ORDER BY id), NULL) AS group_num 
    FROM @my_table t 
) 
SELECT *, IIF(fruit IS NULL, DENSE_RANK() OVER(PARTITION BY group_num ORDER BY id), 1) rnk 
FROM Base b 
ORDER BY id 

결과 :

id fruit  group_num rnk 
--- --------- --------- --- 
100 apple  NULL  1 
125 apple  NULL  1 
150 NULL  2   1 
175 pineapple NULL  1 
200 banana NULL  1 
225 NULL  4   1 
250 NULL  4   2 
275 orange NULL  1 
300 NULL  5   1 
325 NULL  5   2 
350 NULL  5   3 
관련 문제