2016-09-20 2 views
0

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

<A|B><1|2><city> 

Здесь <city> является полем, возвращаемый запросом. Окончательный набор данных должен иметь 4 копии каждой записи: например, если город Бостон, то кодовые значения являются:

A1Boston 
A2Boston 
B1Boston 
B2Boston 

Все остальное в этих 4 записей должен быть одинаковым, и я должен сгенерируйте эти 4 записи для каждой записи в исходном запросе.

Есть ли программный способ сделать это, кроме (1) создания временной таблицы с комбинациями значений кода, затем присоединения к ней или (2) выбора в переменную и итерации по ней? Я действительно должен сделать то же самое для нескольких других одинаково больших запросов, поэтому я хотел бы сделать что-то повторяемое, если это возможно.

Спасибо!

+0

Является ли код динамическим или фиксированным? – Boneist

ответ

0

Если я правильно понимаю вашу потребность, это может быть способ решить:

with test(something, city) as 
(
    select 1, 'Boston' from dual union all 
    select 1, 'Boston' from dual union all 
    select 1, 'Boston' from dual union all 
    select 1, 'Boston' from dual union all 
    select 1, 'Boston' from dual union all 
    select 6, 'N.Y.' from dual union all 
    select 6, 'N.Y.' from dual union all 
    select 6, 'N.Y.' from dual union all 
    select 7, 'L.A.' from dual union all 
    select 7, 'L.A.' from dual 
) 
select case when RN in (1, 2) then 'A' else 'B' end 
     || 
     case when RN in (1, 3) then '1' else '2' end, 
     city, 
     something 
from (
     select city, something, row_number() over (partition by city order by null) as RN 
     from test 
    ) 
where RN <= 4   
0

вы можете использовать вспомогательный запрос для генерации префиксов значения, и чем присоединиться к нему с запросом

select 
    prefix || city, field1, field2 ... 
from 
    (select city, field1, field2 ... /* your query */) 
cross join 
    (select 'A1' as prefix from dual 
    UNION ALL 
    select 'A2' as prefix from dual 
    UNION ALL 
    select 'B1' as prefix from dual 
    UNION ALL 
    select 'B2' as prefix from dual 
) 

выберите

1

Предполагая, что значение кода является статическим, может быть, это даст вам представление о том, как это сделать:

WITH sample_data AS (SELECT 1 ID, 'Boston' city FROM dual UNION ALL 
        SELECT 2 ID, 'New York' city FROM dual UNION ALL 
        SELECT 3 ID, 'Detroit' city FROM dual) 
SELECT dummy1.col1||dummy2.col1||sd.city results 
FROM sample_data sd 
     CROSS JOIN (SELECT 'A' col1 FROM dual UNION ALL 
        SELECT 'B' col1 FROM dual) dummy1 
     CROSS JOIN (SELECT LEVEL col1 
        FROM dual 
        CONNECT BY LEVEL <= 2) dummy2 
ORDER BY sd.city, dummy1.col1, dummy2.col1; 

RESULTS 
------------------------------------------------- 
A1Boston 
A2Boston 
B1Boston 
B2Boston 
A1Detroit 
A2Detroit 
B1Detroit 
B2Detroit 
A1New York 
A2New York 
B1New York 
B2New York 

Имея два кросс-соединения, вы облегчите изменение запроса, если вы измените значение кода, например. < A | B | C > < 1 | 2 | 3 | 4 > <city> - если вы были жестко кодированы строки для перекрестного соединения (например, «A1», «A2», «A3» и т. Д.), Вы бы выписать все 12 комбинаций вместо того, чтобы просто работать с 7 указанными значениями в значении кода.

+0

Это решение тоже получает мой голос - декартово (или «крест») соединение - лучшее решение в этом типе проблем. – mathguy

+0

@Boneist Perfect, это именно то, что мне нужно (и это тоже элегантно). Я попробовал это вчера, и он отлично поработал. Спасибо за вашу помощь! – Nester

Смежные вопросы