我想知道哪个是将任意字符串转换为列的更好/更快/更有效的方法:
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
版本的唯一原因是因为它是在Example of Data Pivots in SQL (rows to columns and columns to rows)中建议的(参见“从两行到六行(一列到一行到一行)”部分。)
我只有SELECT
访问我正在使用的Oracle数据库,因此无法运行EXPLAIN PLAN
。我之前也尝试过使用WITH ... AS
,但没有运气。
答案 0 :(得分:1)
除了最微不足道的行之外,我会使用connect by。没有解释计划虽然很痛苦......你真的把手绑在那里。我真的很想知道优化者对基数的估计是什么。
答案 1 :(得分:1)
我认为你混淆了“SQL中的数据枢轴示例(行到列和列到行)”中使用的目的UNION ALL和CONNECT BY方法“
您问题中的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