PDA

View Full Version : بررسی راه حل های مساله معروف Gaps



محمد سلیم آبادی
پنج شنبه 28 مرداد 1389, 02:42 صبح
سلام دوستان،
صورت مساله
ابتدا جدول را ایجاد کرده و داده های آزمایشی را در آن انتشار دهید:


-- dbo.NumSeq (numeric sequence with unique values, interval: 1)
IF OBJECT_ID('dbo.NumSeq', 'U') IS NOT NULL DROP TABLE dbo.NumSeq;
CREATE TABLE dbo.NumSeq
(
seqval INT NOT NULL
CONSTRAINT PK_NumSeq PRIMARY KEY
);
INSERT INTO dbo.NumSeq(seqval) VALUES
(2),(3),(11),(12),(13),(27),(33),(34),(35),(42);


به اعداد متوالی توجه کنید. اعدادی ما بین 3 و 11 وجود ندارند و همچنین ما بین 13 و 27 فضای گپ وجود دارد، وظیفه ی ما بدست آوردن رنج اعداد از دست رفته است. یعنی نتیجه دلخواه به این شکل است:


start_point end_point
----------- -----------
4 10
14 26
28 32
36 41

آقای Ben Gan سه روش با کوئری معرفی کرده اند.
من نیز به غیر از روش های معرفی شده توسط ایشان 5 روش دیگر خلق کرده.
اولین روشم را در کد زیر مشاهده می کنید:


;WITH C AS
(
SELECT MIN(seqval) AS minimum,
MAX(seqval) AS maximum,
ROW_NUMBER() OVER(ORDER BY MIN(seqval)) AS rownum
FROM (SELECT seqval, ROW_NUMBER() OVER(ORDER BY seqval) - seqval AS grp_factor
FROM NumSeq
) D
GROUP BY grp_factor
)
SELECT MAX(CASE WHEN k = 1 THEN maximum END) + 1 AS start_point,
MAX(CASE WHEN k = 2 THEN minimum END) - 1 AS end_point
FROM C
CROSS JOIN
(VALUES (1),(2)
) AS D(k)
GROUP BY (CASE k WHEN 1 THEN rownum + 1
WHEN 2 THEN rownum
END)
HAVING COUNT(*) = 2;