2017-06-26 15 views
0

ちょっとテーブルから欠損値を取得しようとしましたが、CTEと再帰なしでどのように取得できるかわかりません。 以下は私の現在のコードですが、前に述べたように再帰で動作します。テーブル内の欠損値を見つける方法

DROP TABLE #temp; 
CREATE TABLE #temp (
    val INT NULL 
); 
DECLARE @val AS INT = 1; 

WHILE @val <= 10 
BEGIN 
    INSERT #temp (val) 
    SELECT cast((RAND()*10) as int); 
    SET @val = @val + 1; 
END 

SELECT * 
FROM #temp; 

WITH CTE AS 
(

    SELECT nMin = MIN(t.val), MAX(t.val) as 'nMax' 
    FROM #temp t 
    UNION ALL 

    SELECT nMin + 1, nMax 
    FROM CTE 
    WHERE nMin < nMax 
) 


SELECT c.nMin 
FROM CTE c 
WHERE NOT EXISTS 
(
    SELECT val 
    FROM #temp 
    WHERE c.nMin = val 
) 

答えて

1

欠損値のない数字のリストが必要なだけで、反対結合を行うことができます。

これらの値を再帰で生成しようとしています。システムテーブルに対してROW_NUMBERを使用する方がはるかに効率的です。システムテーブルを十字で結合して、必要な数だけ番号を取得し、TOP句を使用して結果を制限することができます。ユーザテーブルのないデータベースであっても、システム定義のオブジェクトが存在します。

私はコードを残して、違いを比較できるようにしました。 これを十分に使用すると、データベースに数値テーブルを持たせる価値があります。集計表とも呼ばれます。

CREATE TABLE #temp (
    val INT NULL 
); 
DECLARE @val AS INT = 1; 

WHILE @val <= 10 
BEGIN 
    INSERT #temp (val) 
    SELECT cast((RAND()*10) as int); 
    SET @val = @val + 1; 
END 

SELECT * 
FROM #temp ORDER BY val; 

WITH CTE AS 
(

    SELECT nMin = MIN(t.val), MAX(t.val) as 'nMax' 
    FROM #temp t 
    UNION ALL 

    SELECT nMin + 1, nMax 
    FROM CTE 
    WHERE nMin < nMax 
) 

,CTE_NUMBERS AS 
(
    SELECT TOP(10) 
     ROW_NUMBER() OVER(ORDER BY (SELECT 1 as d)) as nMin 
    FROM sys.all_objects AS a 
    CROSS JOIN sys.all_objects AS b 
) 

SELECT c.nMin 
FROM CTE_NUMBERS c 
WHERE NOT EXISTS 
(
    SELECT val 
    FROM #temp 
    WHERE c.nMin = val 
) 

DROP TABLE #temp 
関連する問題