我有一个看起来像这样的表:
A 1
A 2
B 1
B 2
我想生成一个如下所示的结果集:
A 1 2
B 1 2
是否有可以执行此操作的 SQL 语句?我正在使用甲骨文。
相关问题:
- 从单行返回多行 我的问题与这个问题的相反。
- 使用 LINQ 连接 这正是我想要做的,但没有 LINQ。
我有一个看起来像这样的表:
A 1
A 2
B 1
B 2
我想生成一个如下所示的结果集:
A 1 2
B 1 2
是否有可以执行此操作的 SQL 语句?我正在使用甲骨文。
相关问题:
(警告-WM_CONCAT
是在 12c 版中删除的不受支持的功能。除非您使用的是非常旧的数据库,否则应避免使用此功能。您可能应该LISTAGG
改用。)
这取决于您使用的 Oracle 版本。如果它支持 wm_concat() 函数,那么您可以简单地执行以下操作:
SELECT field1, wm_concat(field2) FROM YourTable GROUP BY field2;
wm_concat() 基本上就像MySQL 中的group_concat()一样工作。它可能没有记录在案,所以启动 ye olde sqlplus 并查看它是否存在。
如果它不存在,那么您将需要自己实现一些等效的东西。您可以在 oracle-base.com的字符串聚合页面中找到有关如何执行此操作的说明。
相当老的话题,但它可以帮助其他人,因为甲骨文同时改进了。
LISTAGG功能是您正在寻找的(至少在 11g 中)
在Oracle 10g+
:
SELECT *
FROM (
SELECT *
FROM mytable
MODEL
PARTITION BY
(grouper)
DIMENSION BY
(ROW_NUMBER() OVER (PARTITION BY grouper ORDER BY id) AS rn)
MEASURES
(val, val AS group_concat, 0 AS mark)
RULES SEQUENTIAL ORDER (
group_concat[rn > 1] ORDER BY rn = group_concat[CV() - 1] || ', ' || val[CV()],
mark[ANY] ORDER BY rn = PRESENTV(mark[CV() + 1], 0, 1)
)
)
WHERE mark = 1
ORDER BY
grouper
请参阅我的博客中的这篇文章以获得解释:
尝试类似:
SELECT
field1,
RTRIM(REPLACE(REPLACE(XMLAgg(XMLElement("x", field2) ORDER BY field2), '<x>'), '</x>', ' ')) AS field2s
FROM yourTable
GROUP BY field1
受到此 Oracle 论坛中的答案的启发。
编辑:这个解决方案被证明是资源密集型的,请求涉及 10 5行。我最终按照John 的建议用自定义聚合函数替换了它。
如果你有 10g,那么你必须通过下面的函数:
CREATE OR REPLACE FUNCTION get_separated_value (input_val in number)
RETURN VARCHAR2
IS
return_text VARCHAR2(10000) := NULL;
BEGIN
FOR x IN (SELECT col2 FROM table_name WHERE col1 = input_val) LOOP
return_text := return_text || ' ' || x.col2 ;
END LOOP;
RETURN return_text;
END;
/
所以,你可以这样做:
select col1, get_separated_value(col1) from table_name
如果你有 oracle 11g,你可以使用listagg:
SELECT
age,
LISTAGG(name, ' ') WITHIN GROUP (ORDER BY name) "names"
FROM table_x
GROUP BY age
SELECT a , COLLECT(b) FROM foo GROUP BY a
在 pl/sql 中使用时非常有用 - 可以转换为用户定义的集合。
用户定义的聚合函数: http: //www.adp-gmbh.ch/ora/sql/user_def_agg.html
只需复制/粘贴并使用它。适用于 9i。