- 浏览: 1022417 次
- 性别:
- 来自: 天津
文章分类
- 全部博客 (445)
- Java (22)
- J2EE (18)
- Flex (102)
- Flex-blazeds (1)
- Flex-FABridge (2)
- Flex4 (3)
- CheckStyle (2)
- PowerDesigner (0)
- POI (2)
- Java2Word (2)
- 杂项 (15)
- 日记 (3)
- 数据库-oracle (41)
- 数据库-SQLServer (7)
- 中间件 (1)
- 英语 (8)
- C# (43)
- ASP.net (72)
- ASP.net MVC (28)
- 微软-Entity Framework (19)
- JavaScript (22)
- JQuery (31)
- EasyUI (3)
- VS2010 (4)
- CVS (1)
- Tomcat (3)
- Linux (1)
- 遗留问题 (1)
- iphone (1)
- MAC (0)
- 系统 (2)
- Web Service (4)
- Cache Manager (1)
- PMP (1)
- WCF (10)
- BootstrapJs (1)
- Web API (6)
- Go语言 (0)
- 网络协议 (2)
- Redis (10)
- RabbitMQ (10)
- Git (3)
- Kafka (5)
- ELK (5)
- Nginx (3)
- 测试 (2)
最新评论
-
ygm0720:
Table行拖拽自己实现 -
程乐平:
Flex4开发视频教程(27集)下载http://bbs.it ...
Flex4教程 -
liuweihug:
Jquery+asp.net 后台数据传到前台js进行解析的办 ...
AJAX $.toJSON的用法或把数组转换成json类型 -
weilikk:
谢谢谢谢!!
javascript IE下不能用 trim函数解决方法 -
gxz1989611:
vigiles 写道请问楼主:[Fault] exceptio ...
blazeds推送技术至Flex
怎么合并多行记录的字符串,一直是oracle新手喜欢问的SQL问题之一,关于这个问题的帖子我看过不下30个了,现在就对这个问题,进行一个总结。
什么是合并多行字符串(连接字符串)呢,例如:
SQL> desc test;
Name Type Nullable Default Comments
------- ------------ -------- ------- --------
COUNTRY VARCHAR2(20) Y
CITY VARCHAR2(20) Y
SQL> select * from test;
COUNTRY CITY
-------------------- --------------------
中国 台北
中国 香港
中国 上海
日本 东京
日本 大阪
要求得到如下结果集:
------- --------------------
中国 台北,香港,上海
日本 东京,大阪
实际就是对字符实现一个聚合功能,我很奇怪为什么Oracle没有提供官方的聚合函数来实现它呢:)
下面就对几种经常提及的解决方案进行分析(有一个评测标准最高★★★★★):
1.被集合字段范围小且固定型 灵活性★ 性能★★★★ 难度 ★
这种方法的原理在于你已经知道CITY字段的值有几种,且还不算太多,如果太多这个SQL就会相当的
长。。看例子:
SQL> select t.country,
2 MAX(decode(t.city,'台北',t.city||',',NULL)) ||
3 MAX(decode(t.city,'香港',t.city||',',NULL))||
4 MAX(decode(t.city,'上海',t.city||',',NULL))||
5 MAX(decode(t.city,'东京',t.city||',',NULL))||
6 MAX(decode(t.city,'大阪',t.city||',',NULL))
7 from test t GROUP BY t.country
8 /
COUNTRY MAX(DECODE(T.CITY,'台北',T.CIT
-------------------- ------------------------------
中国 台北,香港,上海,
日本 东京,大阪,
大家一看,估计就明白了(如果不明白,好好补习MAX DECODE和分组)。这种方法无愧为最笨的方法
,但是对某些应用来说,最有效的方法也许就是它。
2.固定表固定字段函数法 灵活性★★ 性能★★★★ 难度 ★★
此法必须预先知道是哪个表,也就是说一个表就得写一个函数,不过方法1的一个取值就要便捷多了。在大多数应用中,也不会存在大量这种合并字符串的需求。废话完毕,看下面:
定义一个函数
create or replace function str_list( str_in in varchar2 )--分类字段
return varchar2
is
str_list varchar2(4000) default null;--连接后字符串
str varchar2(20) default null;--连接符号
begin
for x in ( select TEST.CITY from TEST where TEST.COUNTRY = str_in ) loop
str_list := str_list || str || to_char(x.city);
str := ', ';
end loop;
return str_list;
end;
使用:
SQL> select DISTINCT(T.country),list_func1(t.country) from test t;
COUNTRY LIST_FUNC1(T.COUNTRY)
-------------------- ----------------
中国 台北, 香港, 上海
日本 东京, 大阪
SQL> select t.country,str_list(t.country) from test t GROUP BY t.country;
COUNTRY STR_LIST(T.COUNTRY)
-------------------- -----------------------
中国 台北, 香港, 上海
日本 东京, 大阪
这个时候,使用分组和求唯一都可以满足要求。它的原理就是,根据唯一的分组字段country,在函数里面再次查询该字段对应的所有被合并列,使用PL/SQL将其合并输出。
3.灵活表函数法 灵活性★★★ 性能★★★ 难度 ★★★
该方法是在方法2的基础上,使用动态SQL,将表名和字段名称传入,从而达到灵活的目的。
create or replace function str_list2( key_name in varchar2,
key in varchar2,
coname in varchar2,
tname in varchar2 )
return varchar2
as
type rc is ref cursor;
str varchar2(4000);
sep varchar2(2);
val varchar2(4000);
cur rc;
begin
open cur for 'select '||coname||'
from '|| tname || '
where ' || key_name || ' = :x '
using key;
loop
fetch cur into val;
exit when cur%notfound;
str := str || sep || val;
sep := ', ';
end loop;
close cur;
return str;
end;
SQL> select test.country,
2 str_list2('COUNTRY', test.country, 'CITY', 'TEST') emplist
3 from test
4 group by test.country
5 /
COUNTRY EMPLIST
-------------------- -----------------
中国 台北, 香港, 上海
日本 东京, 大阪
4.一条SQL法 灵活性★★★★ 性能★★ 难度 ★★★★
一条SQL的法则是某位大师提出的,大家曾经在某个时期都乐此不彼的寻求各种的问题一条SQL法,但是大师的意思似乎被曲解,很多性能差,可读性差,灵活差的SQL都是这个原则产物,所谓画虎不成反成犬类。不过,解决问题始终是第一原则,这里还是给出一个比较有代表性的一条SQL方法。
SELECT country,max(substr(city,2)) city
FROM
(SELECT country,sys_connect_by_path(city,',') city
FROM
(SELECT country,city,country||rn rchild,country||(rn-1) rfather
FROM
(SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY
test.city) rn
FROM test))
CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0')
GROUP BY country;
下面分步解析,有4个FROM,就有4次结果集的操作。
step 1 给记录加上序号rn
SQL> SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER
BY test.city) rn
2 FROM test
3 /
COUNTRY CITY RN
-------------------- -------------------- ----------
日本 大阪 1
日本 东京 2
中国 上海 1
中国 台北 2
中国 香港 3
step 2 创造子节点父节点
SQL> SELECT country,city,country||rn rchild,country||(rn-1) rfather
2 FROM
3 (SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER
BY test.city) rn
4 FROM test)
5 /
日本 大阪 日本1 日本0
日本 东京 日本2 日本1
中国 上海 中国1 中国0
中国 台北 中国2 中国1
中国 香港 中国3 中国2
step 3 利用sys_connect_by_path生成结果集
SELECT country,sys_connect_by_path(city,',') city
FROM
(SELECT country,city,country||rn rchild,country||(rn-1) rfather
FROM
(SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER BY
test.city) rn
FROM test))
CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0'
日本 ,大阪
日本 ,大阪,东京
中国 ,上海
中国 ,上海,台北
中国 ,上海,台北,香港
step 4 最终步骤,筛选结果集合
SQL> SELECT country,max(substr(city,2)) city
2 FROM
3 (SELECT country,sys_connect_by_path(city,',') city
4 FROM
5 (SELECT country,city,country||rn rchild,country||(rn-1) rfather
6 FROM
7 (SELECT test.country ,test.city,row_number() over (PARTITION BY test.country ORDER
BY test.city) rn
8 FROM test))
9 CONNECT BY PRIOR rchild=rfather START WITH rfather LIKE '%0')
10 GROUP BY country;
COUNTRY CITY
-------------------- -------
中国 上海,台北,香港
日本 大阪,东京
可谓是,7歪8搞,最后还是弄出来了,呵呵。
5.自定义聚合函数 灵活性★★★★★ 性能★★★★★ 难度 ★★★★★
最后一个方法是我认为“王道”的方法,自定义聚合函数。
就如何我在本开始说的,为啥oracle没有这种聚合函数呢?我也不知道,但oracle提供了聚合函数的
API可以让我方便的自己定义聚合函数。
详细可以看Oracle Data Catridge guide这个文档。连接如下:
http://www.oracle.com.cn/other/9ionlinedoc/appdev.920/a96595/toc.htm
下面给出一个简单的例子:
SQL> SELECT t.country,strcat(t.city) FROM test t GROUP BY t.country;
COUNTRY STRCAT(T.CITY)
-------------------- ------------------
日本 东京,大阪
中国 台北,香港,上海
简单吧,和官方的函数一样的便捷高效。
函数:
CREATE OR REPLACE FUNCTION strcat(input varchar2 )
RETURN varchar2
PARALLEL_ENABLE AGGREGATE USING strcat_type;
TYPE:
create or replace type strcat_type as object (
cat_string varchar2(4000),
static function ODCIAggregateInitialize(cs_ctx In Out strcat_type) return number,
member function ODCIAggregateIterate(self In Out strcat_type,value in varchar2) return
number,
member function ODCIAggregateMerge(self In Out strcat_type,ctx2 In Out strcat_type)
return number,
member function ODCIAggregateTerminate(self In Out strcat_type,returnValue Out
varchar2,flags in number) return number
)
6.待发掘...
总结,合并字符串还有更多的方法希望大家能发掘,本文的目的主要是抛砖引玉,如果有新的发现我会继续更新方法。需要注意的问题是,本文采用varchar2为例子,所以长度有限制,oracle的版本对方法的实现也影响。
发表评论
-
数据库主键到底是用自增长(INT)好还是UUID好
2018-03-09 17:02 950之前在参加长沙互联 ... -
MySQL、Oracle和SQL Server的分页查询语句
2017-01-06 14:10 703假设当前是第PageNo页,每页有PageSize条记录,现 ... -
Oracle job为什么不能自动执行,手工执行可以
2016-02-26 10:11 1072用sysdba登录,执行show parameter jo ... -
oracle job 定时执行 存储过程
2016-02-26 10:10 6038oracle job 定时执行 存储过程 ... -
oracle查询表结构
2010-10-18 16:50 2608方法1 --按照表明查询 select * fr ... -
Oracle错误一览表(3)
2010-07-31 16:20 2265ORA-09751: pw_attachPorts: 服务器调 ... -
Oracle错误一览表(2)
2010-07-31 16:20 4549ORA-02201: 此处不允许序列(号) ORA-02202 ... -
Oracle错误一览表(1)
2010-07-31 16:19 2224ORA-00001: 违反唯一约束条件 (.) ORA-000 ... -
用于表空间和表分区的方法
2010-07-08 14:07 1199CREATE OR REPLACE FUNCTION MASA ... -
oracle中查看用户权限
2010-06-17 09:16 12351.查看所有用户: select * from dba_us ... -
oracle append 用法
2010-06-13 15:24 43821、今天PL/SQL导出数据时,忘将删除记录选项去除。结果,以 ... -
oracle删除重复记录
2010-06-11 11:50 1349比如现在有一人员表 (表名:peosons)若想将姓名、身份证 ... -
Oracle多行记录合并/连接/聚合字符串的几种方法
2010-06-11 11:37 6750怎么合并多行记录的字符串,一直是oracle新手喜欢问的SQL ... -
sqlplus中改变日期的输出格式
2010-06-08 13:04 1691工作中碰到用spool导出数据,其中有日期格式的字段,因为fo ... -
Oracle开发专题之:%TYPE 和 %ROWTYPE
2010-05-18 11:46 14161. 使用%TYPE 在许多情况下,PL/SQL变量可以用 ... -
Oracle过程快查询成条记录,以及如何编写游标
2010-05-18 11:29 1199Declare Cursor emp_cur is ... -
Oracle时间日期操作
2010-05-17 17:31 1157Oracle时间日期操作sysdate+(5/24/60/ ... -
ORACLE常用函数和SQL性能忧化
2010-05-12 22:33 1300NVL(eExpression1, eExpression2) ... -
[Oracle]高效的SQL语句之分析函数(四)--lag()/lead()
2010-05-05 14:55 1261有时候报表上面需要显示该笔操作的上一步骤或者下一步骤的详细信息 ... -
[Oracle]高效的SQL语句之分析函数(三)--row_number() /rank()/dense_rank()
2010-05-05 14:39 1653有些时候我们希望得到指定数据中的前n列,示例如下:得到每个部门 ...
相关推荐
在Oracle数据库中,有时我们需要将多个字段值转换为单个字符串,或者将多行记录合并成一行,这在数据处理和报告生成时尤其常见。Oracle提供了多种方法来实现这一...记住,选择哪种方法取决于数据的特性和需求的复杂性。
Oracle数据库在处理多行记录合并、连接和聚合字符串时,有多种方法,下面将详细介绍其中的几种常见技术。 1. 被集合字段范围小且固定型 这种方法适用于字段值有限且已知的情况。通过使用`DECODE`函数,我们可以为每...
什么是合并多行字符串(连接字符串)呢,例如: SQL> desc test; Name Type Nullable Default Comments ——- ———— ——– ——- ——– COUNTRY VARCHAR2(20) Y CITY VARCHAR2(20) Y SQL> select * from test; ...
本文主要介绍几种常用的字符串连接函数,包括`CONCAT()`、`CONCAT_WS()`以及`GROUP_CONCAT()`函数,并通过示例来详细解释它们的用法及其特性。 #### 1. CONCAT() `CONCAT()`函数用于连接一个或多个字符串值。它...
在PostgreSQL中,有几种方法可以实现字符串拼接: 1. **使用`||`操作符**:这是PostgreSQL中最直观的字符串拼接方式。例如,如果你有两个字符串变量`a`和`b`,你可以通过`a || b`来将它们连接在一起。 ```sql ...
在 MySQL 中,处理字符串拼接有几种非常实用的函数,它们分别是 `CONCAT()`、`CONCAT_WS()` 和 `GROUP_CONCAT()`。这些函数在数据库操作中经常用于构建复合字符串,以满足特定的需求。 1. **CONCAT() 函数** `...
您可能感兴趣的文章:常用的Oracle doc命令(收藏)Oracle 多行记录合并/连接/聚合字符串的几种方法Oracle中字符串连接的实现方法php连接oracle数据库及查询数据的方法plsql连接oracle数据库报ora 12154错
本篇文章将详细介绍Oracle中实现多行记录合并的几种方法,包括使用SQL函数、集合操作以及自定义函数。 1. **使用SQL函数:** - **`LISTAGG()` 函数:** 这是Oracle 11g及以后版本引入的一个强大的聚合函数,专门...
在字符串切分方法中,`split()` 方法的第二个参数可以指定切分几次,该参数表示切分操作执行的次数。例如,`split("", 2)` 表示将字符串切分为最多两个部分。 字典和列表的操作是Python中处理集合类型数据的基础...
在Oracle中,如果没有WM_CONCAT函数,可以有以下几种替代方法: 1. 使用LISTAGG函数:从Oracle 11g开始,官方提供了LISTAGG函数,它可以按照指定的分隔符连接字符串。例如: ```sql SELECT LISTAGG(column, ', ')...
- **字符串表达式**:用于字符串操作。 - **时间值表达式**:涉及日期和时间的计算。 - **时间间隔值表达式**:用于表示时间间隔。 - **运算符的优先级**:明确了运算符的执行顺序。 ##### 1.6 DM_SQL语言支持的...
在MySQL数据库中,`CONCAT()`函数是一种非常实用的字符串操作函数,用于将一个或多个字符串连接成一个单一的字符串。这个函数的基本语法是 `CONCAT(str1, str2, ...)`,它会将所有传入的参数拼接在一起。如果任何一...
首先,`Web.Config` 文件是 ASP.NET 应用程序的核心配置文件,包含了应用程序的全局设置,如数据库连接字符串、身份验证模式、会话状态设置以及错误处理等。在聚合支付的上下文中,`Web.Config` 可能会包含与第四方...
该方法返回一个字符串,表示生成的 RSS 数据的 HTML 格式。 在使用 LoadRSS 方法时,需要注意以下几点: * RSS 的地址必须是正确的,否则将抛出异常。 * RssCount 参数应该大于 0,否则将返回空字符串。 * 在遍历 ...
varchar2 1~4000字节 可变长度字符串,与CHAR类型相比,使用VARCHAR2可以节省磁盘空间,但查询效率没有char类型高 数值类型 Number(m,n) m(1~38) n(-84~127) 可以存储正数、负数、零、定点数和精度为38位的浮点数...
本文将详细介绍MySQL中的常用函数,分为数学函数、聚合函数、字符串函数和日期与时间函数四大类。 1. 数学函数: - ABS(x):计算并返回x的绝对值。 - BIN(x):将十进制数x转换为二进制字符串。 - CEILING(x):...
- `InStr(字符串1,字符串2)`:在字符串1中查找字符串2的起始位置。 - `Ucase$(字符串)`:将字符串转为大写。 - `Lcase$(字符串)`:将字符串转为小写。 6. **窗体输入输出函数**: - `Print(字符串)`:在窗体上...
- CHARINDEX():用于返回子字符串在字符串中首次出现的位置。 - PATINDEX():返回字符串中某个模式的起始位置,可以使用通配符。 - LEN():返回字符串的长度。 - LEFT() 和 RIGHT():分别返回字符串左侧或右侧的...