2011-12-18 18 views
0

我有一個包含兩個相關列,一個ID和一個雙精度浮點數的表格,表示這樣的座標:(x1,y1,x2,y2,x3 ,y3,...)。這個陣列的長度從四到幾十不等。在Oracle中編寫一個SQL視圖,該視圖爲另一個表中的每行返回多行

我需要寫一個觀點,即需要所有這些行,和他們每個人的應用擴展到幾行與訂單場,就像這樣:

 
ID order X Y 
1 1 x1 y1 
1 2 x2 y2 
1 3 x3 y3 
2 1 x1 y1 
2 2 x2 y2 
2 3 x3 y3 

谷歌是沒有幫助,而且被別人只能在平庸SQL(大多數在PostgreSQL中),Oracle文檔不可能找到高級的東西。

+0

是每個實行已知/常量「創建」的行數? – Yahia 2011-12-18 07:52:31

+0

No.我更新了這個問題,所以要說 – Brad 2011-12-18 15:40:59

+0

你需要顯示錶格的定義和VARARRAY ... – Yahia 2011-12-18 15:45:32

回答

2

我爲自己喜歡piplined表,繼承人一個使用它的解決方案:

create or replace type my_res_typ as object 
(
    v_id number, 
    v_order number, 
    x  number, 
    y  number 
) 
; 
/

CREATE OR REPLACE TYPE my_res_tab AS TABLE OF my_res_typ; 
/

create or replace function get_coordinates return my_res_tab 
    pipelined is 

    Result my_res_typ := my_res_typ(null, null, null, null); 
    seq number; 
    i  integer; 
begin 

    for r in (select * from my_table) loop 
    seq := 1; 

    i := r.coordinates.first; 
    while i < r.coordinates.last loop 
     Result.v_id := r.id; 
     Result.v_order := seq; 
     Result.x  := r.coordinates(i); 
     Result.y  := r.coordinates(i + 1); 

     pipe row(Result); 
     seq := seq + 1; 
     i := i + 2; 
    end loop; 

    end loop; 

    return; 
end get_coordinates; 
/

現在你可以查詢它是這樣的:

select * from table(get_coordinates); 

我用

MY_TABLE

作爲表名

+0

這正是我所知道的必須可能的事情。我實際上是通過谷歌偶然發現了「流水線」的東西,但所有的例子都是如此微不足道,它們並沒有真正展示任何東西。謝謝! – Brad 2011-12-19 05:53:49

0
+0

不,它不能。 'Pivot'可以獲取多行數據並將它們轉換爲單行。 'Unpivot'可以做相反的事情,但是它不能完成存儲在用戶定義類型中的數據。 – Allan 2011-12-19 21:08:55

+0

它是這樣做的,只有它默認使用用戶定義的類型作爲字符串9,你可以進行轉換或轉換) – Naval 2011-12-22 06:42:11

0

下面是使用解析函數沿着table函數,以產生所需的數據集,而無需使用存儲的過程的例子。

CREATE OR REPLACE TYPE number_list AS VARRAY(10) OF NUMBER 
/

CREATE TABLE my_table(id NUMBER, coordinates number_list) 
/

INSERT INTO my_table(id, coordinates) 
VALUES  (1, number_list(4,5,6,7,8,9)); 

INSERT INTO my_table(id, coordinates) 
VALUES  (2, number_list(10,11,12,13,14,15)); 

SELECT id, 
     coordinateset, 
     SUM(CASE suborder WHEN 1 THEN coordinate ELSE NULL END) AS x, 
     SUM(CASE suborder WHEN 2 THEN coordinate ELSE NULL END) AS y 
FROM  (SELECT id, 
       coordinate, 
       DENSE_RANK() OVER (PARTITION BY id ORDER BY CEIL(roworder/2)) AS coordinateset, 
       DENSE_RANK() OVER (PARTITION BY id, CEIL(roworder/2) ORDER BY roworder) AS suborder 
      FROM (SELECT a.id, b.COLUMN_VALUE AS coordinate, ROWNUM AS roworder 
        FROM my_table a, table(coordinates) b)) 
GROUP BY id, coordinateset 
ORDER BY id, coordinateset; 

使用ROWNUM是我唯一不確定的東西。雖然在受控環境下,它似乎總是使用varray指示的順序,但我不確定此行爲是否得到保證。

最後,爲了說明這一點,這是一個非常糟糕的設計。即使您使用將數據拆分爲兩個表格的適當關係設計來解決問題,您仍然可以使用用戶定義類型的varray,它們專門指示哪些x和y值屬於一起。

相關問題