对异构数据库进行关联查询

例题描述和简单分析

Oracle数据库中,有 BRANCH 表,存储 DVD 分店信息,部分数据如下所示:

BID

STREET

CITY

B001

street1

New York

B002

street2

Houston

B003

street3

LA

B004

street4

Lincoln

MySQL数据库中,有 DVD 表,存储 DVD 的标题及分类信息,部分数据如下所示:

DVDID

CATEGORY

TITLE

D001

science fiction

Transformers IV

D002

science fiction

Transformers II

D003

science fiction

Guardians of the Galaxy

D004

act

The Expendables III

D005

sport

Need for Speed

D006

feature

Grace of Monaco

DVDID

Category

Title

HSQL数据库中,有 DVDCOPY 表,存储 DVD 的多张拷贝,部分数据如下所示:

COPYID

DVDID

BID

STATUS

LASTDATERENTED

LASTDATERETURNED

MEMBERID

C000

D001

B001


7/10/2014

7/13/2014

M001

C001

D004

B001


7/10/2014

7/13/2014

M001

C002

D001

B001


7/10/2014


M001

C003

D005

B001


7/10/2014

7/13/2014

M003

C004

D006

B001


7/10/2014

7/13/2014

M003

C005

D005

B002


7/10/2014

7/13/2014

M003

C006

D002

B002


7/10/2014

7/13/2014

M006

C007

D002

B002


7/10/2014

7/13/2014

M007

C008

D001

B002


7/10/2014

7/13/2014

M008

C009

D004

B002


7/10/2014

7/13/2014

M009

C010

D005

B002


7/10/2014

7/13/2014

M010

C011

D006

B002

Miss

7/10/2014

7/13/2014

M010

C000

D001

B003


7/10/2014

7/13/2014

M001

C001

D004

B003


7/10/2014

7/13/2014

M001

C002

D001

B003

Miss

7/10/2014


M001

C003

D005

B003


7/10/2014

7/13/2014

M003

其中 DVDCOPY 表以 BID 字段和 BRANCH 表关联,以 DVDID 字段和 DVD 表关联。

需求 1:找出城市为 New York 的分店中所有的 DVD 拷贝的标题及分类信息,结果如下:

CITY

COPYID

CATEGORY

TITLE

New York

C000

science fiction

Transformers IV

New York

C001

act

The Expendables III

New York

C002

science fiction

Transformers IV

New York

C003

sport

Need for Speed

New York

C004

feature

Grace of Monaco

需求 2:查询出缺货的 DVD 分店,即现存的 DVD 拷贝不到 4 类的分店,结果如下:

BID

STREET

CITY

B002

street2

Houston

B003

street3

LA

B004

street4

Lincoln

解法及简要说明

在集算器中编写脚本 p1.dfx,如下所示:

需求1:简单SQL


A

1

=connect("demo").cursor@x("SELECT   * FROM DVDCOPY")

2

=connect("mysql").cursor@x("SELECT   * FROM DVD")

3

=connect("oracle").cursor@x("SELECT   * FROM BRANCH")

4

$select b.CITY as   CITY,dc.COPYID as COPYID,d.CATEGORY as CATEGORY,d.TITLE as TITLE from {A1} dc   join {A2} d on dc.DVDID=d.DVDID join {A3} b on dc.BID=b.BID where b.CITY='New   York'

简要说明:

A1   连接数据源名为 demo 的数据库(HSQL),返回根据 sql 创建的数据库游标,关闭游标时自动关闭数据库连接

A2   连接数据源名为 mysql 的数据库(MySQL),返回根据 sql 创建的数据库游标,关闭游标时自动关闭数据库连接

A3  连接数据源名为 oracle 的数据库(Oracle),返回根据 sql 创建的数据库游标,关闭游标时自动关闭数据库连接

A3  用简单 SQL 关联三表

需求2SPL


A

1

=BRANCH=connect("oracle").query@x("SELECT   * FROM BRANCH")

2

=DVD=connect("mysql").query@x("SELECT   * FROM DVD")

3

=DVDCOPY=connect("demo").query@x("SELECT   * FROM DVDCOPY")

4

=DVDCOPY.switch(DVDID,DVD:DVDID;BID,BRANCH:BID)

5

=DVDCOPY.select(STATUS!="Miss"   && LASTDATERETURNED!=null)

6

=A5.group(BID)

7

=A6.new(~.BID:BonList,~.(DVDID).icount(CATEGORY):CatCount)

8

=A7.select(CatCount<4)

9

=A8.(BonList)|(BRANCH\A7.(BonList))

简要说明:

A1-A3:从数据库中检索数据,分别命名为变量 BRANCH、DVD、DVDCOPY。

A4:用 switch 函数,将 DVDCOPY 表中的 DVDID 字段切换成 DVD 表中对应的记录,将 BID 字段切换成 BRANCH 表中对应的记录。

A5:过滤数据:丢失的和未归还的 DVD 拷贝不在计算范围内

A6:A5 按 BID 分组,每组代表一个门店的所有 DVD 拷贝

A7:计算每个门店对应的 DVD 拷贝各有几类。函数 new 可以根据 A6 中的数据生成新的对象 A7,A7 有两个列:BonList 和 CatCount,BonList 直接来自 A6 中组内数据的 BID 列,CatCount 来自于组内数据的 DVDID 列。CatCount 的算法分为三部分:~.(DVDID) 找到每个门店所有的 DVD 拷贝对应的 DVD 记录;icount(CATEGORY) 用来计算 CATEGORY 去重后的个数。

A8:在 A7 中找出 CatCount 小于 4 的门店

A9:运算符“|”表示将两个数据集进行并集计算(可用 union 函数代替),运算符“\”表示差集计算(可用 diff 函数代替)。A8.(BonList)、BRANCH、A7.(BonList) 分别代表:DVDCOPY 表中缺货的门店、所有的门店、DVDCOPY 表中出现过的门店

JAVA 集成这段代码的方法可参考:《Java 如何调用 SPL 脚本》

问答搜集

https://stackoverflow.com/questions/16991792/java-library-for-cross-database-retrieval