2012-10-16 12 views
0

我有一個看起來像這樣的數據:確定起點和覆蓋期末 - Oracle 10g的SQL

 ID  FROM  TO   START_CODE  END_CODE TYPE 
     A  01/01/2012 02/02/2012 P    E   1 
     A  12/03/2011 01/01/2012 P    X   1 
     A  01/01/2011 12/03/2011 S    X   2 

     A  01/01/2010 02/02/2010 P    E   2 
     A  12/03/2010 01/01/2010 P    X   4 
     A  01/01/2009 12/03/2009 S    X   1 

基本上,這是一個客戶端信息。 end_code'e'表示護理期結束,start_code''表示護理期的開始。起始碼'p'表示日期是延續,'x'結束碼也是。我希望能夠返回的數據,看起來像下面這樣:

 ID  START  END    Types 
     A  01/01/2011 02/02/2012  2,1,1 
     A  01/01/2009 02/02/2010  1,4,2 

第一個表查詢類似於這樣(只是舉例),但是,我有興趣返回了許多的客戶,而不僅僅是'A'。

 SELECT 
     A.ID, 
     A.FROM, 
     A.TO, 
     A.START_CODE, 
     A.END_CODE, 
         A.Type 

     WHERE 
     A.ID = 'A' 

我使用XMLAGG在過去取得類似的事情(即列出一個小區信息),但它實際上標識單獨開始和結束日期爲每個客戶端,然後返回類型的序列我正在努力。作爲參考,我的oracle版本是10g,10.2.0.5.0。

感謝您的時間,任何指針或援助表示讚賞。基於ABCade的解決方案

 SELECT 
     t3.MOV_PER_GRO_ID, 
     t3.f, 
     t3.MOV_END_DATE, 
     t3.types, 
     LENGTH(REGEXP_REPLACE(t3.types,'[^,]')) as "Count" 
     FROM(

     SELECT 
     sys_connect_by_path(t2.MOV_2000_PLACEMENT_TYPE,',') types, 
     connect_by_root(t2.MOV_START_DATE) f, 
     t2.MOV_START_DATE,   
     t2.MOV_END_DATE,   
     connect_by_isleaf is_leaf, 
     t2.MOV_PER_GRO_ID 
     FROM (SELECT t.*, 
     lag(t.MOV_START_DATE) over (ORDER BY t.MOV_PER_GRO_ID, t.MOV_START_DATE) nfrom 
     FROM O_MOVEMENTS t 
     WHERE t.MOV_PER_GRO_ID IN ('A','B'))t2 
     START 
     WITH 
     t2.MOV_2000_START_REASON = 'S' 
     CONNECT BY 
     PRIOR t2.MOV_START_DATE = t2.nfrom 
     AND PRIOR t2.MOV_PER_GRO_ID = t2.MOV_PER_GRO_ID 
     AND t2.MOV_2000_START_REASON IN ('P'))t3 
     where t3.is_leaf=1 

更新時間:

編輯以低於A.B.Cade包括建議。經過一些調整(再次感謝ABCade),它似乎正在工作。

回答

2

嘗試:

SELECT t3."ID", t3.f "start", t3."TO" "end", t3.types 
FROM (
SELECT sys_connect_by_path(t2."TYPE",',') types, 
     connect_by_root(t2."FROM") f, 
     t2."FROM", 
     t2."TO", 
     connect_by_isleaf is_leaf , 
t2."ID" 
FROM (
    SELECT t.*, lag(t."FROM") over (ORDER BY t."FROM") nfrom 
    FROM table1 t 
    WHERE t."ID" = 'A' 
) t2 
START WITH t2."START_CODE" = 'S' 
CONNECT BY PRIOR t2."FROM" = t2.nfrom AND t2."START_CODE" = 'P') t3 
WHERE is_leaf=1 

Here是一個小提琴
Here是另一個小提琴

+0

感謝這個(看到你的評論和更新後),我從來沒有見過一個使用SYS_CONNECT_BY_PATH前查詢,但我會盡快嘗試一下。非常感謝。 – bawpie

+0

@bawpie,如果沒有你的表格定義和一些真實的數據樣本,很難說,但我的猜測是它與我所做的一些假設有關:1)期間可能有gups(這就是爲什麼我使用'lag'並且不能相信「從......到......之前」,2)期間沒有重疊。我沒有考慮使用「ID」字段。如果假設(2)正確,但僅適用於每個「ID」,那麼在最內部的選擇中應該添加「WHERE t。」ID「='A''。 –

+0

@ABCade - 謝謝,我現在正在爲一個ID(查詢中更新的代碼)工作。如果我嘗試在多個id上運行它,有時候我會收到有關ORA-01436:用戶數據中的CONNECT BY循環的錯誤,那麼在連接時是否需要引用該ID?恐怕我不熟悉使用connect by。 – bawpie