UNION ALL против CONNECT BY LEVEL для генерации строк - PullRequest
0 голосов
/ 21 октября 2009

Мне было интересно, какой из них лучше / быстрее / эффективнее превращает произвольные строки в столбцы:

UNION ALL

SELECT my_field,
       CASE WHEN my_field = 'str1'
            THEN ...
            ...
       END,
       ...
FROM (
       SELECT 'str1' AS my_field FROM DUAL
       UNION ALL
       SELECT 'str2' AS my_field FROM DUAL
       UNION ALL
       SELECT 'str3' AS my_field FROM DUAL
     ),
     ...

CONNECT BY LEVEL

SELECT CASE WHEN rowno = 1
            THEN 'str1'
            ...
       END AS my_field,
       CASE WHEN rowno = 1
            THEN ...
            ...
       END,
       ...
FROM (
       SELECT ROWNUM rowno
       FROM DUAL
       CONNECT BY LEVEL <= 3
     ),
     ...

Я склонен использовать версию UNION ALL хотя бы потому, что она упрощает самый внешний SELECT: мне не нужно делать второй оператор CASE, чтобы получить нужные строковые значения. Это также более читабельно, чтобы видеть WHEN my_field = 'str1', а не WHEN rowno = 1. Единственная причина, по которой я спрашиваю о версии CONNECT BY LEVEL, заключается в том, что она была предложена в Пример сводок данных в SQL (строки в столбцы и столбцы в строки) (см. «От двух строк до шести строк (a столбец в строку ») раздел).

У меня есть только SELECT доступ к базе данных Oracle, которую я использую, поэтому я не могу запустить EXPLAIN PLAN. Я тоже пытался использовать WITH ... AS и раньше тоже без удачи.

Ответы [ 2 ]

1 голос
/ 21 октября 2009

Я думаю, что вы путаете целевые методы UNION ALL и CONNECT BY, используемые в "Примере сводок данных в SQL (строки в столбцы и столбцы в строки)"

UNION ALL в вашем вопросе используется для преобразования нескольких строк с одним столбцом в одну строку с несколькими столбцами:

label, 1, val1
label, 2, val2
label, 3, val3

в

label, val1, val2, val3

Подзапрос CONNECT BY используется для преобразования одной строки с несколькими столбцами в несколько строк с одним столбцом, поэтому он использует в качестве подзапроса генератора для умножения существующего набора данных:

label, val1, val2, val3 
+
1
2
3

результат в:

label, 1, val1, val2, val3
label, 2, val1, val2, val3
label, 3, val1, val2, val3

преобразован в:

label, 1, val1
label, 2, val2
label, 3, val3
1 голос
/ 21 октября 2009

Я бы использовал connect by для любого, кроме самого тривиального числа строк. Не иметь объяснения по плану - боль, хотя ... у тебя действительно связаны руки. Я бы очень хотел знать, какова оценка кардинальности оптимизатора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...