2010-01-02 17 views
1

我有一個叫做扇區的表格,每個扇區通常是1,2,3,4,5,6,7等。如何獲取sql中的序列號範圍?

我想在應用程序中顯示可用扇區,我認爲顯示所有1,2,3,4,5,6,7都是啞的,所以我應該顯示「1到7」。

問題是,有時候這些扇區跳過一個像這樣的數字1,2,3,5,6,7。 所以我想展示一些像1到3,5到7.

我怎麼能在sql中查詢這個顯示在我的應用程序?

回答

2

某些DBMS可能具有某些OLAP功能,可以很容易地編寫這樣的查詢,但IBM Informix Dynamic Server(IDS)尚未具備此類功能。

假設,爲了具體起見,你的表稱爲「ProductSectors」和具有如下所示的結構:

CREATE TABLE ProductSectors 
(
    ProductID INTEGER NOT NULL, 
    Sector  INTEGER NOT NULL CHECK (Sector > 0), 
    Name   VARCHAR(20) NOT NULL, 
    PRIMARY KEY (ProductID, Sector) 
); 

你所特定的ProductID內尋求世界上最大和最小的連續名單Sector的值。當沒有小於最小值的值且沒有值大於最大值並且在該範圍內沒有間隙時,範圍是連續的。這是一個複雜的查詢:

SELECT P1.ProductID, P1.Sector AS Min_Sector, P2.Sector AS Max_Sector 
    FROM ProductSectors P1 JOIN ProductSectors P2 
    ON P1.ProductID = P2.ProductID 
    AND P1.Sector <= P2.Sector 
WHERE NOT EXISTS (SELECT *  -- no entry one smaller 
        FROM ProductSectors P6 
        WHERE P1.ProductID = P6.ProductID 
         AND P1.Sector - 1 = P6.Sector 
       ) 
    AND NOT EXISTS (SELECT *  -- no entry one larger 
        FROM ProductSectors P5 
        WHERE P2.ProductID = P5.ProductID 
         AND P2.Sector + 1 = P5.Sector 
       ) 
    AND NOT EXISTS (SELECT *  -- no gaps between P1.Sector and P2.Sector 
        FROM ProductSectors P3 
        WHERE P1.ProductID = P3.ProductID 
         AND P1.Sector <= P3.Sector 
         AND P2.Sector > P3.Sector 
         AND NOT EXISTS (SELECT * 
             FROM ProductSectors P4 
             WHERE P4.ProductID = P3.ProductID 
             AND P4.Sector = P3.Sector + 1 
            ) 
       ) 
ORDER BY P1.ProductID, Min_Sector; 

這裏是整個查詢的樣本數據的工作痕跡:

CREATE TEMP TABLE productsectors 
(
    ProductID INTEGER NOT NULL, 
    Sector  INTEGER NOT NULL CHECK(Sector > 0), 
    Name  VARCHAR(20), 
    PRIMARY KEY (ProductID, Sector) 
); 

和一些示例數據,與各方面的差距:

INSERT INTO ProductSectors VALUES(101, 1, "101:1"); 
INSERT INTO ProductSectors VALUES(101, 2, "101:2"); 
INSERT INTO ProductSectors VALUES(101, 3, "101:3"); 
INSERT INTO ProductSectors VALUES(101, 4, "101:4"); 
INSERT INTO ProductSectors VALUES(101, 5, "101:5"); 
INSERT INTO ProductSectors VALUES(101, 6, "101:6"); 
INSERT INTO ProductSectors VALUES(101, 7, "101:7"); 
INSERT INTO ProductSectors VALUES(102, 1, "102:1"); 
INSERT INTO ProductSectors VALUES(102, 2, "102:2"); 
INSERT INTO ProductSectors VALUES(102, 4, "102:4"); 
INSERT INTO ProductSectors VALUES(102, 5, "102:5"); 
INSERT INTO ProductSectors VALUES(102, 6, "102:6"); 
INSERT INTO ProductSectors VALUES(102, 7, "102:7"); 
INSERT INTO ProductSectors VALUES(103, 1, "103:1"); 
INSERT INTO ProductSectors VALUES(103, 2, "103:2"); 
INSERT INTO ProductSectors VALUES(103, 4, "103:4"); 
INSERT INTO ProductSectors VALUES(103, 6, "103:6"); 
INSERT INTO ProductSectors VALUES(103, 7, "103:7"); 
INSERT INTO ProductSectors VALUES(104, 1, "104:1"); 
INSERT INTO ProductSectors VALUES(104, 2, "104:2"); 
INSERT INTO ProductSectors VALUES(104, 3, "104:3"); 
INSERT INTO ProductSectors VALUES(104, 6, "104:6"); 
INSERT INTO ProductSectors VALUES(104, 7, "104:7"); 
INSERT INTO ProductSectors VALUES(105, 1, "105:1"); 
INSERT INTO ProductSectors VALUES(105, 4, "105:4"); 
INSERT INTO ProductSectors VALUES(105, 5, "105:5"); 
INSERT INTO ProductSectors VALUES(105, 7, "105:7"); 
INSERT INTO ProductSectors VALUES(106, 1, "106:1"); 
INSERT INTO ProductSectors VALUES(106, 2, "106:1"); 
INSERT INTO ProductSectors VALUES(106, 3, "106:1"); 
INSERT INTO ProductSectors VALUES(106, 7, "106:7"); 
INSERT INTO ProductSectors VALUES(107, 7, "107:7"); 
INSERT INTO ProductSectors VALUES(108, 8, "108:8"); 
INSERT INTO ProductSectors VALUES(108, 9, "108:9"); 

所需輸出 - 也是實際輸出:

101|1|7 
102|1|2 
102|4|7 
103|1|2 
103|4|4 
103|6|7 
104|1|3 
104|6|7 
105|1|1 
105|4|5 
105|7|7 
106|1|3 
106|7|7 
107|7|7 
108|8|9 

預計結果爲MacOS X 10.6.2,IDS 11.50.FC4W1,SQLCMD 86.04。

0

好吧,我一直在尋找更深入,發現this

它的工作原理:),希望它可以幫助別人,因爲它幫助了我。

2

這被稱爲sql中的「差距」。以下是詳細的文章:"Article"