取分组后的第一条数据

【问题】

Hello- Any help on writing SQL query to retrieve one record for each employee from the following table? preferably a standard SQL.

EmpNum Alternate Contact Relation PhType Phone  
============================================  
123456 Rick Grimes SP Cell 9999999999  
123456 Rick Grimes SP Work 8888888888  
123457 Daryl Dixon FR Work 7777777777  
123457 Daryl Dixon FR Home 3333333333  
123458 Maggie Greene CH Cell 5555555555  
123458 Maggie Greene CH Home 6666666666  

expected result:

EmpNum Alternate Contact Relation PhType Phone  
=================================================  
123456 Rick Grimes SP Cell 9999999999  
123457 Daryl Dixon FR Work 7777777777  
123458 Maggie Greene CH Home 6666666666  

【回答】

如果按照 SQL2003 的标准,那么使用窗口函数可以解决你的问题,即:按 EmpNum 分组,按规则取出每组第一条,规则可以是:组内序号,某个字段的排序位置。比如按电话号码升序排列并取第一条,SQL 如下:

SELECT empnum, alternate, contact, relation, phtype, phone

FROM (

       SELECT a.*, row_number() over(PARTITION BY empnum ORDER BY phone ASC) rid  
       FROM t1 a)

WHERE rid = 1

但是,目前的数据库对窗口函数实现程度各有不同,有些根本就没有实现。如果按照 SQL92 的标准,得用 JOIN 拼出窗口函数中序号的效果,难度就很大了。这时候,可以尝试一下 SPL,它支持直接按组内序号取数据,这个问题写出来只要一句:



A

1

=db.query("select * from t1")

2

=A1.group@1(EmpNum)


更复杂的情况还可参考【SPL 简化 SQL 案例详解:计算各组前 N 行】。

集算器提供 JDBC 接口与 JAVA 程序或报表工具集成,与使用数据库差不多,详情可参考【Java 如何调用 SPL 脚本】