2013-06-11 34 views
7

Tôi có một bảng với các định nghĩa sau đâyLàm thế nào để tìm ra ranh giới của các nhóm các số liên tiếp?

CREATE TABLE mytable 
    (
    id  INT IDENTITY(1, 1) PRIMARY KEY, 
    number BIGINT, 
    status INT 
) 

và ví dụ dữ liệu

INSERT INTO mytable 
VALUES (100,0), 
     (101,0), 
     (102,0), 
     (103,0), 
     (104,1), 
     (105,1), 
     (106,0), 
     (107,0), 
     (1014,0), 
     (1015,0), 
     (1016,1), 
     (1017,0) 

Nhìn chỉ ở hàng nơi status = 0 làm thế nào tôi có thể thu gọn Number giá trị vào dãy số thứ tự tiếp giáp và tìm ra bắt đầu và kết thúc của mỗi phạm vi?

ví dụ: Đối với các dữ liệu ví dụ kết quả sẽ là

  FROM  to 
Number 100  103 
Number 106  107 
Number 1014  1015 
Number 1017  1017 
+0

Tôi đã thực hiện việc này trước đây, vài tháng trước. Tôi không nghĩ rằng tôi đã lưu truy vấn, nhưng nó vẫn có thể nằm trong nhật ký cục bộ của tôi. Giữ chặt. –

+3

google cho "lỗ hổng và đảo của máy chủ sql" – OzrenTkalcecKrznaric

+0

xin lỗi tôi không thể tìm thấy nó. –

Trả lời

25

Như đã đề cập trong các ý kiến ​​này là một khoảng trống và các đảo vấn đề cổ điển.

Một giải pháp được Itzik Ben Gan phổ biến là sử dụng thực tế là ROW_NUMBER() OVER (ORDER BY number) - number vẫn không đổi trong một "đảo" và không thể xuất hiện ở nhiều đảo.

WITH T 
    AS (SELECT ROW_NUMBER() OVER (ORDER BY number) - number AS Grp, 
       number 
     FROM mytable 
     WHERE status = 0) 
SELECT MIN(number) AS [From], 
     MAX(number) AS [To] 
FROM T 
GROUP BY Grp 
ORDER BY MIN(number) 

NB: Nếu number không đảm bảo là duy nhất thay thế ROW_NUMBER với DENSE_RANK trong đoạn code trên.

+0

+1: Vâng, đây là cách tiếp cận tốt nhất. Không có con trỏ bị nguyền rủa hoặc đệ quy không hiệu quả cần thiết. – RBarryYoung

+0

Nhân vật thiên tài của bạn! Cảm ơn bạn rất nhiều –

+3

Đây là một trong những nơi mà Itzak nói về nó: http://www.sqlmag.com/article/tsql3/calculating-concurrent-sessions-part-3. Tôi sẽ không đề cập đến người mà anh ta đã ghi có bằng cách giải quyết nó (bên cạnh Ben Flanaghan và Arnold Fribble). ;-) – RBarryYoung

Các vấn đề liên quan