我有一张这样的表:
+-------+-------+-------+-------+
| ID | City | Param | Value |
+-------+-------+-------+-------+
| id1 | city1 | a | value |
| id2 | city1 | b | value |
| id3 | city1 | c | value |
| id4 | city2 | a | value |
| id5 | city2 | b | value |
| id6 | city2 | c | value |
| ... | ... | ... | ... |
| idN | cityN | a | value |
| idN+1 | cityN | b | value |
| idN+2 | cityN | c | value |
+-------+-------+-------+-------+
正如您所看到的,每个城市都有一个子表格,如:
+-------+-------+
| Param | Value |
+-------+-------+
| a | value |
| b | value |
| c | value |
+-------+-------+
所以我想加入所有子表并得到一个这样的表:
+-------+-------+-------+-----+-------+
| Param | city1 | city2 | ... | cityN |
+-------+-------+-------+-----+-------+
| a | value | value | ... | value |
| b | value | value | ... | value |
| c | value | value | ... | value |
+-------+-------+-------+-----+-------+
我有什么想法可以得到它吗?
提前谢谢!
注1:城市数量是可变的。
注2:解决方案可以是PL / SQL函数。
答案 0 :(得分:1)
为了获得您想要的结果,您需要 pivot 数据。虽然您说plsql可能是一个选项,但您没有指定您正在使用的Oracle版本。从Oracle 11g开始,PIVOT
功能可用。
如果您没有使用Oracle 119,那么您可以使用带有CASE
表达式的聚合函数:
select param,
max(case when city = 'city1' then value end) City1,
max(case when city = 'city2' then value end) City2
from yourtable
group by param
由于您声明您将拥有未知数量的city
值,因此您需要创建此查询的动态sql版本。您可以创建类似于此的过程:
CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor)
as
sql_query varchar2(1000) := 'select param ';
begin
for x in (select distinct city from yourtable order by 1)
loop
sql_query := sql_query ||
' , max(case when city = '''||x.city||''' then value else null end) as '||x.city;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from yourtable group by param order by param';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
然后,要获得结果,您可以使用以下内容(注意:我在TOAD中使用此):
variable x refcursor
exec dynamic_pivot(:x)
print x
您的查询结果将是:
| PARAM | CITY1 | CITY2 |
-------------------------
| a | value | value |
| b | value | value |
| c | value | value |
答案 1 :(得分:0)
如果你有10G,你可以使用11G中的新pivot
或model
子句。
检查文档。