a表
ID Name
1张三
2李四
多表left join3王五
4王陆
a表left join b表结果ID Name Description 1张三内联部
1张三系学⽣会
2李四外联部
3王五团委
4王陆NULL SQLDistinct处理多列的问题
今天在做SSIS的ETL⼯作时,其中⼀个left join组件的运⾏结果总是会多出⼀些记录。分析了⼀下,该问题的原因是右表中作为关联的那⼀列数据有重复。left join的运⾏策略可以理解为根据左表的每⼀条记录的关联字段去对照右表的关联字段,如果右表的关联字段存在重复,就会⽣成重复的记录。如果左表存在重复⽽右表⽆重复,则不会多出来记录。举个例⼦,如果左表a和右表b的数据分别如下所⽰
b表
ID Description
1内联部
1系学⽣会
2外联部
3团委
这时如果⽤ID作为关联字段⽤a表left join b表,结果会产⽣5条记录,⽐左表多⼀条。(顺便提⼀下,如果右表不重复,则left join的结果数会与左表相等)
实际上,我想要的结果是与左表a⼀⼀对应,不要有重复的记录。这可以通过SSIS的lookup组件实现,但是效率会很低。因此就想到把右表中的重复记录去除掉再join两张表。⾸先⾃然地想到⽤distinct函数去重
SELECT DISTINCT ID, Description
FROM B
结果却是1条记录都没去掉,因为Distinct是作⽤于多列的,也就是说必须要ID和Description全都相同的才会被剔除。
在⽹上搜了⼀下,有⼈说⽤ select *, count(distinct name) from table group by name 这样的语句是可⾏的,但我在SQL Server⾥⾯试了⼀下会报错。只好⾃⼰动⼿,丰⾐⾜⾷啦,想了⼀下,其实可以⽤下⾯的语句
SELECT ID, Max(Description) AS Description
FROM B
GROUP BY ID
进⼀步的思考后发现,SQL Server中有First_Value和Last_Value函数,也可以实现
SELECT DISTINCT ID, FIRST_VALUE(Description) OVER (PARTITION BY ID
ORDER BY Description) AS Description
FROM B
第⼆种⽅法中Partition by的参数必须是ID,Order by的参数可以调整,这就使得该⽅法更加灵活。这两种⽅法经实测效率差不多,第⼀种稍微快⼀点点。不过遗憾的是SSIS中不⽀持第⼆种⽅法,只能⽤第⼀种group by的⽅式。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论