Oracle/SQL — несколько записей в одну [агрегация строк]

Я понимаю, что это нелепый запрос, но я пытаюсь вернуть несколько записей в один столбец вместе с некоторым буквальным текстом.

Итак, учитывая такую ​​​​таблицу

REGION  CITY    SID
-------------------
1   Chicago     1234
1   Palatine    567
1   Algonquin   234
1   Wauconda    987

Я хотел бы вернуть одну запись со столбцом, другие столбцы, такие как регион, в порядке, но один такой столбец

<option value="1234">Chicago</option><option value="567">Palatine</option><option value="234">Algonquin</option><option value="987">Wauconda</option>

Любые мысли о том, как это сделать? Я использую Oracle 9i и не могу сделать это в PL/SQL.


Хорошо, формат таблицы немного изменился, но идея та же.

COUNTRY STORECODE   STORE_NAME
------------------------------
USA     1234        Chicago
USA     567         Palatine
CAN     987         Toronto

Итак, я нашел этот код, пройдя по перечисленным ссылкам

SELECT COUNTRY,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(STORECODE,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS COUNTRY_HTML
FROM   (SELECT COUNTRY,
               STORECODE,
               ROW_NUMBER() OVER (PARTITION BY COUNTRY ORDER BY STORECODE) AS curr,
               ROW_NUMBER() OVER (PARTITION BY COUNTRY ORDER BY STORECODE) -1 AS prev
        FROM   tablename)
GROUP BY COUNTRY
CONNECT BY prev = PRIOR curr AND COUNTRY = PRIOR COUNTRY
START WITH curr = 1;

И когда я запускаю его, я вижу этот вывод

COUNTRY COUNTRY_HTML
--------------------
USA     1234,567
CAN     987

Моя мысль заключалась в том, чтобы просто получить внутренний выбор из другого выбора, где я выполняю свою конкатацию STORECODE и STORE_NAME вместе с требуемым html, как это...

SELECT COUNTRY,
       LTRIM(MAX(SYS_CONNECT_BY_PATH(RECORD_HTML,','))
       KEEP (DENSE_RANK LAST ORDER BY curr),',') AS COUNTRY_HTML
FROM   (SELECT COUNTRY,
               RECORD_HTML,
               ROW_NUMBER() OVER (PARTITION BY COUNTRY ORDER BY RECORD_HTML) AS curr,
               ROW_NUMBER() OVER (PARTITION BY COUNTRY ORDER BY RECORD_HTML) -1 AS prev
        FROM   (SELECT COUNTRY, '<option value="' || STORECODE || '">' || STORE_NAME || '</option>' AS RECORD_HTML FROM tablename))
GROUP BY COUNTRY
CONNECT BY prev = PRIOR curr AND COUNTRY = PRIOR COUNTRY
START WITH curr = 1;

Хотя наша интерфейсная среда принимает запрос, когда я пытаюсь просмотреть результаты, я получаю сообщение об ошибке: ресурс недействителен. Возможно, вам придется заново создать или исправить запрос перед просмотром.

Я знаю, что эта ошибка, вероятно, бесполезна, но есть идеи, почему моя версия не работает?

Спасибо!


person dscl    schedule 22.02.2012    source источник
comment
Вы действительно уверены, что не можете сделать это в своем приложении?   -  person WW.    schedule 23.02.2012
comment
возможный дубликат быстрого способа создания объединенных строк в Oracle   -  person Jon Heller    schedule 23.02.2012
comment
ВВ. Я, конечно, буду настаивать на этом, но в случае, если мы не можем или просто в качестве учебного упражнения, было бы здорово иметь возможность это сделать.   -  person dscl    schedule 23.02.2012


Ответы (3)


Это отвратительно, но вы можете сделать что-то вроде этого:

select replace(blah2,',','')
  from ( select wm_concat(blah) as blah2
           from ( select '<option value="' || sid || '">' || city || '</option>' as blah
                    from my_table
                         )
                 )
person Ben    schedule 22.02.2012
comment
Я знаю, вы сказали, что это отвратительно, но это также может быть XML-инъекцией. Если вы выберете этот подход, вам нужно экранировать sid и город XML. - person WW.; 23.02.2012
comment
И просто чтобы было сложнее - любые мысли о том, как сделать это без использования wm_concat() - person dscl; 23.02.2012
comment
@dscl, обратите внимание, я не оправдываю этого. Просто указал на это как на решение. Вы должны принять к сведению комментарий WW. Поскольку вы находитесь на 9i, я бы предложил stragg, что, как я доказал, идентично ограничение до wm_concat, извините... Другие способы были бы хуже. - person Ben; 23.02.2012

Вы играли с DBMS_XMLGEN?

person Mike McAllister    schedule 22.02.2012
comment
Это действительно ответ? Разве это не должно быть просто комментарием? - person Ollie; 23.02.2012
comment
Вы бы предпочли, чтобы я перефразировал это, поскольку DBMS_XMLGEN позволит вам делать то, что вы ищете? - person Mike McAllister; 23.02.2012
comment
Я не критикую, просто то, что вы написали, больше похоже на комментарий, чем на полезный ответ. Простое упоминание DBMS_XMLGEN также не будет очень полезным, краткое объяснение специфики будет соответствовать ИМХО. - person Ollie; 23.02.2012

Вы можете создать агрегатную функцию в Oracle, см. документацию.

person Amir Pashazadeh    schedule 22.02.2012