2016-06-02 4 views
2

私は自分のレコードに連続したヌル値をランクしたいと思います。すべてのレコードのランクは1になります。一度しか表示されないNULL値の場合、ランクも1になります。ただし、連続して表示されるNULL値の場合、ランクは最初のレコードでは1、2番目のレコードでは2になりますレコードなど。ここに私のコードです。連続したヌル値の順位付け

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

? –

+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

は(32767レベルに制限=〜行はソリューションによって異なります)、また、2つのagregate/ranking関数(SUMおよびDENSE_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 

結果:SQL Serverのバージョン

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 
関連する問題