2012-09-07 30 views
24

kimlikleri eksik olsun:MySQL örneğin, ben MySQL bu tablo var tablodan

ID | Name 
1 | Bob 
4 | Adam 
6 | Someguy 

fark ederseniz, hiçbir kimlik numarasıdır (2, 3 ve 5).

MySQL'in yalnızca eksik kimlikleri yanıtlayabilmesi için bir sorguyu nasıl yazabilirim, bu durumda: "2,3,5"?

cevap

14

Daha verimli sorgusu: Eğer tek bir sütunda eksik sayılarını almak için bu deneyebilirsiniz böylece iki sütun verecek sorgular Üstü

SELECT (t1.id + 1) as gap_starts_at, 
     (SELECT MIN(t3.id) -1 FROM my_table t3 WHERE t3.id > t1.id) as gap_ends_at 
FROM my_table t1 
WHERE NOT EXISTS (SELECT t2.id FROM my_table t2 WHERE t2.id = t1.id + 1) 
HAVING gap_ends_at IS NOT NULL 
+0

Teşekkür Ivan çok yavaş. Bu çok daha hızlı çalışır! – MikeC

+0

Bu benim için çalıştı, ancak ilk boşluk eksik id = 1 – egprentice

2

select start from 
(SELECT a.id+1 AS start, MIN(b.id) - 1 AS end 
    FROM sequence AS a, sequence AS b 
    WHERE a.id < b.id 
    GROUP BY a.id 
    HAVING start < MIN(b.id)) b 
UNION 
select c.end from (SELECT a.id+1 AS start, MIN(b.id) - 1 AS end 
    FROM sequence AS a, sequence AS b 
    WHERE a.id < b.id 
    GROUP BY a.id 
    HAVING start < MIN(b.id)) c order by start; 
+0

Bu tek sütunlu sürümü ile, (örneğin) '475', '477',' 506', '508',' 513 Ama iki sütunlu versiyonu ile bana [475,475] '' '[477,506]' '[508,513]' i, 475, 477-506 ve 508-513 sayılarını kaçırdığımı söyler. –

1

Ivan'ın cevabına biraz eklemek için, versiyon gösterileri numaralar 1 yoksa başında eksik:

SELECT 1 as gap_starts_at, 
     (SELECT MIN(t4.id) -1 FROM testtable t4 WHERE t4.id > 1) as gap_ends_at 
FROM testtable t5 
WHERE NOT EXISTS (SELECT t6.id FROM testtable t6 WHERE t6.id = 1) 
HAVING gap_ends_at IS NOT NULL limit 1 
UNION 
SELECT (t1.id + 1) as gap_starts_at, 
     (SELECT MIN(t3.id) -1 FROM testtable t3 WHERE t3.id > t1.id) as gap_ends_at 
FROM testtable t1 
WHERE NOT EXISTS (SELECT t2.id FROM testtable t2 WHERE t2.id = t1.id + 1) 
HAVING gap_ends_at IS NOT NULL; 
İlgili konular