12

インタビューで次のような質問を受けました: 自然数のテーブルに欠けているものがある場合、最初のテーブルの数のギャップの始まりと 2 番目のテーブルで終わる 2 つのテーブルの出力を提供してください。例:

____ ________
| | | | | | | | | |
| | 1 | | | 3 | 3 |
| | 2 | | | 6 | 7 |
| | 4 | | | 10| 12|
| | 5 | |___|___|
| | 8 |
| | 9 |
| | 13 |
|____|
4

7 に答える 7

7

これは Phil Sandler の回答とほとんど同じですが、これは 2 つの別個のテーブルを返すはずです (そして、よりきれいに見えると思います) (少なくとも SQL Server では機能します)。

DECLARE @temp TABLE (num int)
@temp 値に挿入 (1)、(2)、(4)、(5)、(8)、(9)、(13)

DECLARE @min INT、@max INT
SELECT @min = MIN(数値)、@max = MAX(数値) FROM @temp

SELECT t.num + 1 AS range_start
    FROM @temp t
    LEFT JOIN @temp t2 ON t.num + 1 = t2.num
    WHERE t.num < @max AND t2.num IS NULL

SELECT t.num - 1 AS range_end
    FROM @temp t
    LEFT JOIN @temp t2 ON t.num - 1 = t2.num
    WHERE t.num > @min AND t2.num IS NULL
于 2010-09-24T16:54:20.903 に答える
2

これは SQL Server の構文です。

CREATE TABLE #temp (columnA int)

INSERT INTO #temp VALUES(1)
INSERT INTO #temp VALUES(2)
INSERT INTO #temp VALUES(4)
INSERT INTO #temp VALUES(5)
INSERT INTO #temp VALUES(8)
INSERT INTO #temp VALUES(9)
INSERT INTO #temp VALUES(13)

SELECT 
    t1.columnA - 1
FROM 
    #temp t1
    LEFT JOIN #temp t2 ON t1.columnA = t2.ColumnA + 1
WHERE 
    t2.ColumnA IS NULL
    AND t1.ColumnA != (SELECT MIN(ColumnA) from #temp)  

SELECT 
    t1.columnA + 1
FROM 
    #temp t1
    LEFT JOIN #temp t2 ON t1.columnA = t2.ColumnA - 1
WHERE 
    t2.ColumnA IS NULL  
    AND t1.ColumnA != (SELECT MAX(ColumnA) from #temp)  

DROP table #temp
于 2010-09-24T15:49:41.503 に答える
2

これはDB固有のSQLなしで機能し、おそらく少しきれいにすることができますが、機能します

編集: StackExchange Data Explorer の このクエリでこれが機能していることを確認できます。

SELECT low,high FROM 

(

SELECT col1, low 

FROM
(Select n1.col1 col1, min(n2.col1) + 1 low
 from numbers n1
inner join numbers n2
on n1.col1 < n2.col1 

Group by n1.col1) t
WHERE t.low not in (SELECT col1 FROM NUMBERS)
and t.low < (Select MAX(col1) from numbers) 
) t

INNER JOIN 
(

SELECT col1 - 1 col1, high
 FROM
(Select n1.col1 col1 , min(n2.col1) - 1 high
 from numbers n1
inner join numbers n2
on n1.col1 < n2.col1 

Group by n1.col1) t
WHERE t.high not in (SELECT col1 FROM NUMBERS) 
) t2
ON t.col1 = t2.col1
于 2010-09-24T16:41:29.290 に答える
2

Itzik Ben Ganは、これらの「ギャップと島」の問題について多くのことを書いています。これに対する彼のrow_number解決策は

WITH C AS
(
SELECT N, ROW_NUMBER() OVER (ORDER BY N) AS RN
FROM t
)
SELECT Cur.N+1,Nxt.N-1
FROM C AS Cur 
JOIN C AS Nxt ON Nxt.RN = Cur.RN+1
WHERE Nxt.N-Cur.N>1

row_numberそして、同じソースからのソリューションはありません。

SELECT N+1 AS start_range,
(SELECT MIN(B.N) FROM t AS B WHERE B.N > A.N)-1 AS end_range
FROM t AS A
WHERE NOT EXISTS(SELECT * FROM t AS B WHERE B.N = A.N+1)
AND N< (SELECT MAX(N) FROM t)
于 2010-09-24T16:30:49.573 に答える
1

このようなもの:

SELECT col1, col2 FROM
(
    SELECT x + 1 as col1, 
        ROW_NUMBER() OVER(ORDER BY x) AS 'rownum'  
    FROM tbl y 
    WHERE NOT EXISTS (SELECT x FROM tbl z WHERE z.x = y.x + 1) 
        AND x <> (SELECT MAX(x) FROM tbl)
) a
INNER JOIN
(
    SELECT x - 1 as col2,
        ROW_NUMBER() OVER(ORDER BY x) AS 'rownum'  
    FROM tbl y 
    WHERE NOT EXISTS (SELECT x FROM tbl z WHERE z.x = y.x - 1) 
        AND x <> (SELECT MIN(x) FROM tbl)
) b
ON a.rownum = b.rownum

「rownum」構文は、DBMS によって異なります。上記は SQL Server で機能する可能性がありますが、テストしていません。

コメントの 1 つが指摘したように、多くの DBMS には、これを容易にする分析機能があります。

于 2010-09-24T15:38:19.707 に答える