2017-06-26 2 views
0

Hey ich versuche, fehlende Werte aus meiner Tabelle zu bekommen, aber ich habe keine Ahnung, wie ich es ohne CTE und Rekursion bekommen kann. Unten ist mein aktueller Code, aber es funktioniert mit Rekursion wie ich schon sagte.So finden Sie fehlende Werte in der Tabelle

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 
) 

Antwort

1

Sie müssen nur eine Liste von Zahlen ohne fehlende Werte, so können Sie gegen eine Anti-Join tun.

Jetzt versuchen Sie, diese Werte mit Rekursion zu generieren. Es ist viel effizienter, ROW_NUMBER für eine Systemtabelle zu verwenden. Sie können die Systemtabelle durchkreuzen, um so viele Zahlen wie gewünscht zu erhalten, und eine TOP-Klausel verwenden, um die Ergebnisse zu begrenzen. Auch in einer Datenbank ohne Benutzertabellen gibt es systemdefinierte Objekte.

Ich habe Ihren Code eingegeben, damit Sie die Unterschiede vergleichen können. Wenn Sie dies oft genug verwenden, kann es sich lohnen, eine Nummerentabelle in Ihrer Datenbank zu haben. Auch Tally-Tabelle genannt.

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 
Verwandte Themen