数据旋转及DB2递归的应用

前几天做一调查,需要下边这样的一个转换。

 

求一SQL--于数据转换

A中有以下数据

A1 1 01

A1 1 02

A1 1 03

A2 1 01

A2 2 01

A2 2 02

希望一SQL够查出下边这样的数据(暂时A中第三列只有01-03可能

A1 1 01-02-03

A2 1 01

A2 2 01-02

 

后来看过别人SQL后,我想出了这么一个笨招。

另外根据tanfufasql,我下午在回家的路上突然想到了一个方法,就是第三列几个字符串,但完全可以定种规则转成一些数字,譬如01成数字1,02成数字2,03成数字4,04话转成数字8,依此推。

然后group sum,根据sum就可以推知是由哪几个字符串值组成的了。

这种方法恐怕就是解析sum值这块需要花费过多的代了。另外不知道db2中有无将十制数字成二制的函数。

所以又了我昨的想法,已经测试成功了。放出其中个最重要的函数,主要是实现转换和解析个二

 

CREATE FUNCTION DB2ADMIN.DEC(VAL_SUM INTEGER)

RETURNS     VARCHAR(20)

    LANGUAGE SQL

    DETERMINISTIC

    NO EXTERNAL ACTION

    CONTAINS SQL

    INHERIT SPECIAL REGISTERS

   

 

   BEGIN ATOMIC

     DECLARE @PARA INT;

    DECLARE @DIV INT;

    DECLARE @MOD INT;

    DECLARE @BIN varchar(20);

    DECLARE @RET varchar(30);

    SET @BIN = '';

    SET @RET = '';

   

    SET @PARA = VAL_SUM;

   

    SET @DIV =@PARA/2;

    SET @MOD = MOD(@PARA,2);

   

    WHILE @PARA <> 0 DO

   

       SET @BIN = rtrim(ltrim(char(@MOD))) || rtrim(ltrim(@BIN));

       SET @PARA = @PARA/2;

       SET @DIV =@PARA/2;

       SET @MOD = MOD(@PARA,2);

    END WHILE;

 

   

    SET @BIN = REPEAT('0',10 - length(@BIN)) || @BIN;

    

    IF substr(@BIN,1,1) = '1' THEN

     SET  @RET = 'NW';

    END IF;

   

        IF substr(@BIN,2,1) = '1' THEN

     SET  @RET = @RET || '-' || 'RE';

    END IF;

   

        IF substr(@BIN,3,1) = '1' THEN

     SET  @RET = @RET || '-' || 'RB';

    END IF;

   

        IF substr(@BIN,4,1) = '1' THEN

    SET  @RET = @RET || '-' || 'RF';

    END IF;

   

        IF substr(@BIN,5,1) = '1' THEN

    SET  @RET = @RET || '-' || 'SV';

    END IF;

   

        IF substr(@BIN,6,1) = '1' THEN

     SET  @RET = @RET || '-' || 'NP';

    END IF;

   

        IF substr(@BIN,7,1) = '1' THEN

     SET  @RET = @RET || '-' || 'NC';

    END IF;

   

        IF substr(@BIN,8,1) = '1' THEN

     SET  @RET = @RET || '-' || 'CC';

    END IF;

   

        IF substr(@BIN,9,1) = '1' THEN

     SET  @RET = @RET || '-' || 'DC';

    END IF;

   

        IF substr(@BIN,10,1) = '1' THEN

     SET  @RET = @RET || '-' || 'AD';

    END IF;

   

    IF length(@RET) > 0 THEN

     IF substr(@RET,1,1) = '-' THEN

       SET @RET = substr(@RET,2);

     END IF;

    END IF;

 

    RETURN rtrim(ltrim(@RET));

  END

 

;

接着呢,我这块砖就引出了玉。呵呵。

 

db2递归的一个例子

myfriend2010

ORACLE中大家可能对递归(在oracle中很多人称作家族)已很熟悉,因ORACLE中的递归较简单,也容易掌握!接触DB2候,也碰到过递归问题,因研究的人少所以接触的候,db2有一神秘的感db2是很大的疑!就sql而言,凡是oraclesql实现的,db2肯定或多或少也可以实现,只是逻辑复杂点!因一直有人提问这边问题,所以今天抽时间写了一点

 

首先,db2递归的一点基

 

db2中的递归查询使用with实现,也称公共表达式,公共表达式在select句的始部分采用with子句的形式,在使用公共表达式的查询中可以多次使用它,并且公共表达式可以通名来接到他本身,这样就可以达到循的目的。

 

递归查询通常有3个部分需要定

 

一:一个公共表达式形式的虚表。

二:一个初始化表。

三:一个与虚行完全内接的助表。

 

需要使用UNION all合并上3查询,然后用select递归输出中得到最果。

 

大体上如下形式

with XX(x1,x2,x3) as  -------@0

(

select a.s,a.s1 from a  ----@1

union all  ----@2

select * from a,xx where a.s=xx.x1 ------@3

)

select ... from xx where .... -------@4

 

@0:with体,即虚

@1:初始化表,里需要定初始化的一些行,也就是你递归的出点,或者父行,部分逻辑行一次,它的果作递归的初始化内容。

@2:里必UNION all

@3:里需要定义递归的条件(助表),里定义递归逻辑,需要注意的是父行和子行接的逻辑一定要清楚父子系,不然很容易成死循的,里首先将初始化表的果作条件查询,在把行的果添加到虚表中,只要里能查询出来记录,那就会行下一步递归

@4:里就是表的查询语句。

 

递归更多的知,可以到google中找更专业料,里只我理解的一些西。

一个简单点的例子:

 

-------------------------------

Q:求一SQL--于数据转换

 

 

A中有以下数据

A1 1 01

A1 1 02

A1 1 03

A2 1 01

A2 2 01

A2 2 02

希望一SQL够查出下边这样的数据(暂时A中第三列只有01-03可能

A1 1 01-02-03

A2 1 01

A2 2 01-02

 

A查询牵扯到全表的递归,用一般的sql句很搞定!

 

是我写的一个递归语句!分享大家看看!

 

为懒,所以把建立测试表的逻辑也略去了,里用with来生成上测试数据。

with t (t1,t2,t3) as (

values

('A1', 1 ,'01'),('A1' ,1, '02'),('A1', 1, '03'),

('A2', 1, '01'),('A2', 2, '01'),('A2', 2 ,'02')

)

select * from t;

测试一下:

 

C:\>db2 connect to dw

 

   数据库连接信息

 

数据         = DB2/NT 8.2.0

SQL 权标识         = DB2ADMIN

本地数据库别       = DW

 

 

C:\>db2 with t (t1,t2,t3) as ( \

db2 (cont.) => values \

db2 (cont.) => ('A1', 1 ,'01'),('A1' ,1, '02'),('A1', 1, '03'), \

db2 (cont.) => ('A2', 1, '01'),('A2', 2, '01'),('A2', 2 ,'02') \

db2 (cont.) => ) \

db2 (cont.) => select * from t

 

T1 T2          T3

-- ----------- --

A1           1 01

A1           1 02

A1           1 03

A2           1 01

A2           2 01

A2           2 02

 

  6 记录选择

 

 

在公布递归逻辑sql如下:

with t (t1,t2,t3) as (

values

('A1', 1 ,'01'),('A1' ,1, '02'),('A1', 1, '03'),

('A2', 1, '01'),('A2', 2, '01'),('A2', 2 ,'02')

),

t1(t11,t22,t33,t44,t55) as (

select t1,t2,t3,rownumber() over(partition by t1,t2),rownumber() over(partition by t1,t2) as t4 from t

),

t3(s1,s2,s3,s4,s5) as(

select t11,t22,cast(t33 as varchar(100)),t44,t55 from t1 where T44 =1 and t55=1

union all

select a.s1,a.s2,cast(a.s3||'-'||b.t33 as varchar(100)),a.s4+1,a.s5 from t3 a,t1 b

where a.s1=b.t11 and a.s4 = b.t55-1)

select s1,s2,s3 from t3 x where x.s4=(select max(s4) from t3 y where x.s1=y.s1) order by s1,s2

;

 

测试一下:

 

 

C:\>db2 connect to dw

 

   数据库连接信息

 

数据         = DB2/NT 8.2.0

SQL 权标识         = DB2ADMIN

本地数据库别       = DW

 

 

C:\>db2 with t (t1,t2,t3) as ( \

db2 (cont.) =>  values \

db2 (cont.) => ('A1', 1 ,'01'),('A1' ,1, '02'),('A1', 1, '03'), \

db2 (cont.) => ('A2', 1, '01'),('A2', 2, '01'),('A2', 2 ,'02') \

db2 (cont.) => ), \

db2 (cont.) =>  t1(t11,t22,t33,t44,t55) as ( \

db2 (cont.) =>  select t1,t2,t3,rownumber() over(partition by t1,t2),rownumber() over(partition by t1,t2) as t4 from t \

db2 (cont.) => ), \

db2 (cont.) => t3(s1,s2,s3,s4,s5) as( \

db2 (cont.) => select t11,t22,cast(t33 as varchar(100)),t44,t55 from t1 where T44 =1 and t55=1 \

db2 (cont.) =>  union all \

db2 (cont.) => select a.s1,a.s2,cast(a.s3||'-'||b.t33 as varchar(100)),a.s4+1,a.s5 from t3 a,t1 b \

db2 (cont.) =>  where a.s1=b.t11 and a.s4 = b.t55-1) \

db2 (cont.) => select s1,s2,s3 from t3 x where x.s4=(select max(s4) from t3 y where x.s1=y.s1) order by s1,s2

 

S1 S2          S3

-- ----------- ----------------------------------------------------------------------------------------------------

SQL0347W  递归公共表表达式 "DB2ADMIN.T3" 可能包含无限循  SQLSTATE=01605

 

A1           1 01-02-03

A2           1 01-02

A2           2 01-02

 

  选择 3 记录,打印 1 条警告消息。

 

 

ok,搞定!

 

个人认为db2是很大的!大家一起学

 

的代逻辑可以了,需要改改

 

 

with t (t1,t2,t3) as (

values

('A1', 1 ,'01'),('A1' ,1, '02'),('A1', 1, '03'),

('A2', 1, '01'),('A2', 2, '01'),('A2', 2 ,'02')

),

t1(t11,t22,t33,t44,t55) as (

select t1,t2,t3,rownumber() over(partition by t1,t2),rownumber() over(partition by t1,t2) as t4 from t

),

t3(s1,s2,s3,s4,s5) as(

select t11,t22,cast(t33 as varchar(100)),t44,t55 from t1 where T44 =1 and t55=1

union all

select a.s1,a.s2,cast(a.s3||'-'||b.t33 as varchar(100)),a.s4+1,a.s5 from t3 a,t1 b where a.s1=b.t11 and a.s2=b.t22  and a.s4 = b.t55-1

)

select s1,s2,s3 from t3 x where x.s4=(select max(s4) from t3 y where x.s1=y.s1 and x.s2=y.s2) order by s1,s2

;

------------------------------------

'A1'        1        '01-02-03'

'A2'        1        01

'A2'        2        '01-02'

 

这样!

转载于:https://www.cnblogs.com/xioxu/archive/2008/03/18/1110796.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/407591.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

stylus之内置方法(Built-in Functions)

内置方法(Built-in Functions) red(color)&#xff1a;返回color中的红色比重 green(color)&#xff1a;返回color中的绿色比重 blue(color)&#xff1a;返回color中的蓝色比重 alpha(color)&#xff1a;返回color中的透明度比重 dark(color)&#xff1a;检查color是否是暗色 …

对进程个数计数

在linux怎么知道一个指定的“进程名”有几个在运行了呢&#xff1f; 下面这下例子演示了这个过程&#xff0c;计数函数为&#xff1a;getProcessCount() #include <stdio.h>#include <stdlib.h>#include <string.h>// 获取进程数量int getProcessCount(char…

如何设计安全的用户登录功能

用户登录功能是Web应用系统具备的最基本的功能&#xff0c;关系到用户数据和应用系统数据的安全&#xff0c;设计一个安全的用户登录功能&#xff0c;涉及到以下几个方面的内容。 (一) 老生常谈——口令 1. 口令长度与复杂度限制 限制用户输入一些非常容易被破解的口令&#xf…

可耗竭且不可回收的资源

第四章可耗竭且不可回收的资源能量是人类最关键的资源&#xff0c;没有它&#xff0c;生命将会终结。第一节天然气&#xff1a;价格控制第二节卡特尔问题• 卡特尔卡特尔是资本主义国家中的垄断组织形式之一&#xff0c;由生产同类产品的企业联合组成。卡特尔成员企业一方面为了…

stylus之其余参数(Rest Params)

其余参数(Rest Params) 其余参数&#xff1a; Stylus支持name…形式的其余参数。这些参数可以消化传递给混写或函数的参数们。这在处理浏览器私有属性&#xff0c;如-moz或-webkit的时候很管用 下面这个例子中&#xff0c;所有的参数们(1px, 2px, …)都被一个args参数给简单…

Taro+react开发(28)本地用require线上不必

img_hongchen: require("../../assets/images/companyTitle/system_video_cover.png"),

FineUI表格模板列Undefined问题

一般是配置文件未添加ClientID"AutoID"引起转载于:https://www.cnblogs.com/fuqiang88/p/3822567.html

fork()使用(一)

第一贴&#xff1a;cu上关于fork()函数的精辟分析 声明&#xff1a;在别人的博客上看到这篇文章&#xff0c;真的很精辟&#xff0c;把问题一下子讲清楚了。所以&#xff0c;特意转贴在此&#xff0c;向各位高人致敬&#xff0c;也向原贴主致谢&#xff01;本人不改变原贴的风貌…

stylus之注释(Comments)

注释(Comments) 注释 Stylus支持三种注释&#xff0c;单行注释&#xff0c;多行注释&#xff0c;以及多行缓冲注释 单行注释&#xff1a; 跟JavaScript一样&#xff0c;双斜杠&#xff0c;CSS中不输出 多行注释&#xff1a; 多行注释看起来有点像CSS的常规注释。然而&a…

吃的文化

主料&#xff1b;发好活海参1条&#xff0c;120克&#xff0c;辅料龙口粉丝10克&#xff0c;蟹黄2克 &#xff0c;五花肉丁10克 西兰花1朵土鸡蛋1个浓汤200克 &#xff0c;海参过水&#xff0c;五花肉煸锅加蚝油2克&#xff0c;金标老抽1克&#xff0c;加浓汤200克 盐味精各一克…

进程初学(二)

首先&#xff0c;来看一下下面的源程序吧&#xff1a; #include <stdio.h>#include <unistd.h>int main(){pid_t pid;printf("Now only one process\n");printf("Calling fork...\n");pid fork();if(!pid){ // 这里是子进程执行的任务printf…

stylus之条件(Conditionals)

条件(Conditionals) 条件&#xff1a; 条件提供了语言的流控制&#xff0c;否则就是纯粹的静态语言。提供的条件有导入、混入、函数以及更多。下面的例子纯粹示例&#xff0c;并不是使用建议 if / else if / else 这没什么好说的&#xff0c;跟一般的语言一致&#xff0c;i…

Taro+react开发(30)引入静态资源地址

<Image mode"widthFix" src{require("./bussness/sysw.jpg")} />

发短信接口获取验证码

接口合作公司 &#xff1a;http://sms.inolink.com/LoginFront.aspx 从这里获取id <?php function execPostRequest($url,$fields){if(empty($url)){ return false;}//$fields_string http_build_query($post_array);foreach($fields as $key>$value) { $fields_strin…

有感于《你赔了我赚了》

昨晚&#xff0c;看了一部电影名叫《你赔了我赚了》。我心情久久不能平静下来&#xff0c;当晚碾转反侧不断地思考着、、、、、这部电影以其极为夸张的手法和特写镜头&#xff0c;聚焦在社会上虚假广告的拍摄&#xff0c;深刻地揭示了当今社会存在的丑陋现象。也正因为这个关系…

Express中use挂载中间件的方法

1.app.use([path,], function [, function…]) 挂载中间件方法到路径上。如果路径未指定&#xff0c;那么默认为”/” 2.一个路由将匹配任何路径如果这个路径以这个路由设置路径后紧跟着”/”。比如&#xff1a;app.use(‘/apple’, …)将匹配”/apple”&#xff0c;”/apple/…

对Ubuntu20.04.2 mate 桌面 Brisk menu 组件的配置

Brisk Menu 让菜单在 mate 桌面上灵活布局&#xff0c; 那个会跳动的精灵还是挺不错的&#xff0c;适当处理后就得到了下面干净利索的桌面。 Ubuntu 安装时&#xff0c;在控制中心留有 plank reference 设置功能&#xff0c;让屏幕中底部的这些组件在不同位置摆放。当进行配置时…