Ниже приведен пример, в котором используются аналитические функции наряду с функцией 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 принадлежат друг другу.