如何查询范围?

时间:2013-04-08 14:27:58

标签: sql range

原始数据

| ID  | STATUS      |
|  1  |      A      |
|  2  |      A      |
|  3  |      B      |
|  4  |      B      |
|  5  |      B      |
|  6  |      A      |
|  7  |      A      |
|  8  |      A      |
|  9  |      C      |

结果

| START      | END    |
|      1     |   2    |
|      6     |   8    |

状态A的范围

如何查询?

3 个答案:

答案 0 :(得分:1)

这应该给你正确的范围:

SELECT
  STATUS,
  MIN(ID),
  max_id
FROM (
  SELECT
    t1.STATUS,
    t1.ID,
    COALESCE(MAX(t2.ID), t1.ID) max_id
  FROM
    yourtable t1 LEFT JOIN yourtable t2
    ON t1.STATUS=t2.STATUS AND t1.ID<t2.ID
  WHERE
    NOT EXISTS (SELECT NULL
                FROM yourtable t3
                WHERE
                  t3.STATUS!=t1.STATUS
                  AND t3.ID>t1.ID AND t3.ID<t2.ID)
  GROUP BY
    t1.ID,
    t1.STATUS
) s
WHERE
  status = 'A'
GROUP BY
  STATUS,
  max_id

请参阅小提琴here

答案 1 :(得分:0)

使用基于游标的解决方案或客户端功能可能会更好。

但是,如果您使用的是Oracle - 以下方法可行。

WITH LOWER_VALS AS
( -- All the Ids with no immediate predecessor
  SELECT ROWNUM AS RN, STATUS, ID AS LOWER FROM
  (
  SELECT STATUS, ID 
  FROM RAWDATA RD1 
  WHERE RD1.ID -1 NOT IN
    (SELECT ID FROM RAWDATA PRED_TABLE WHERE PRED_TABLE.STATUS = RD1.STATUS)
  ORDER BY STATUS, ID
  )
) ,  
UPPER_VALS AS
( -- All the Ids with no immediate successor  
  SELECT ROWNUM AS RN, STATUS, ID AS UPPER FROM
  (
  SELECT STATUS, ID 
  FROM RAWDATA RD2 
  WHERE RD2.ID +1 NOT IN
    (SELECT ID FROM RAWDATA SUCC_TABLE WHERE SUCC_TABLE.STATUS = RD2.STATUS)
  ORDER BY STATUS, ID
  )
)  
SELECT
  L.STATUS, L.LOWER, U.UPPER
FROM 
  LOWER_VALS L
  JOIN UPPER_VALS U ON
    U.RN = L.RN;

集合中的结果

A   1   2

A   6   8

B   3   5

C   9   9

http://sqlfiddle.com/#!4/10184/2

答案 2 :(得分:-1)

你投入的内容并不多,但我认为这可能有用。我使用的是T-SQL因为我不知道你在用什么?

SELECT
    min(ID)
    , max(ID)
FROM RawData 
WHERE [Status] = 'A'