SQL Distinct处理多列的问题

  今天在做SSIS的ETL工作时,其中一个left join组件的运行结果总是会多出一些记录。分析了一下,该问题的原因是右表中作为关联的那一列数据有重复。left join的运行策略可以理解为根据左表的每一条记录的关联字段去对照右表的关联字段,如果右表的关联字段存在重复,就会生成重复的记录。如果左表存在重复而右表无重复,则不会多出来记录。举个例子,如果左表a和右表b的数据分别如下所示

a表
ID Name
1 张三
2 李四
3 王五
4 王陆
b表
ID Description
1 内联部
1 系学生会
2 外联部
3 团委

  这时如果用ID作为关联字段用a表left join b表,结果会产生5条记录,比左表多一条。(顺便提一下,如果右表不重复,则left join的结果数会与左表相等)

a表left join b表结果
ID Name Description
1 张三 内联部
1 张三 系学生会
2 李四 外联部
3 王五 团委
4 王陆 NULL

  实际上,我想要的结果是与左表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,  (SELECT  Max(Description)            FROM    B) AS Description
FROM      BGROUP 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的方式。

时间: 2024-08-10 23:30:08

SQL Distinct处理多列的问题的相关文章

SQL-W3School:SQL DISTINCT 语句

ylbtech-SQL-W3School:SQL DISTINCT 语句 1.返回顶部 1. 本章讲解 SELECT DISTINCT 语句. SQL SELECT DISTINCT 语句 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. 关键词 DISTINCT 用于返回唯一不同的值. 语法: SELECT DISTINCT 列名称 FROM 表名称 使用 DISTINCT 关键词 如果要从 "Company" 列中选取所有的值,我们

sql不显示重复列

在报表里,基本上都可以把重复的资料不显示,在SQL里怎么才能做到如下情况呢? a 10 a 20 b 30 b 40 b 50 显示为: a 10 20 b 30 40 50 SQL 如下: create table #a (part varchar(10),price int) go insert into #a values('a',10) insert into #a values('a',20) insert into #a values('b',30) insert into #a v

sql server拼接一列字段

有一表,名曰IPSlot,欲取IP整列字段. sql语句,利用sql server的xml auto将表数据转换成xml=> 1 select name= 2 STUFF( 3 REPLACE( 4 REPLACE((select IP from IPSlot for xml auto), '<IPSlot IP="', '/') 5 , '"/>', '') 6 , 1, 1, '') 效果=> 关于stuff关键字用法示例=> 1 SELECT STU

sql取出某一列不重复数据的ID解决办法

取出某一列不重复数据的ID表A有ID,BID,ITime三列BID可能会有重复的现在要从A表根据ITime降序排序取出ID来,且如果BID重复就只取第一条数据的ID应该如何实现?------解决方案-------------------- 如果id是递增的select min(id),BID,max(date)from tbl group by BID sql取出某一列不重复数据的ID解决办法,布布扣,bubuko.com

SQL ID自增列从1开始重新排序

开发了android程序就知道,原生的模拟器启动比较慢,还会出现莫名的问题,这边介绍另外一种模拟器: BlueStacks:BlueStacks是一个可以让Android 应用程序运行在Windows系统(目前,该公司再次宣布推出Mac版Bluestacks模拟器.)上的软件,由BlueStacks公司推出.BlueStacks新版本App Player采用名为Layercake的技术,可以让针对ARM处理器开发的安卓应用运行在基于x86处理器的PC或者平板上,而且可以调用PC的显卡,能提供比A

使用sql更改表的列的数据类型和添加新列和约束

使用sql更改表的列的数据类型和添加新列和约束 修改数据库表某一列或添加列 --增加一列 ALTER TABLE 表名 ADD 列名 VARCHAR(20) NULL --删除一列 ALTER TABLE 表名 drop COLUMN 列名 --修改一列 alter TABLE 表名 ALTER COLUMN 列名 VARCHAR(40) NULL --修改一列的类型 alter TABLE 表名 ALTER COLUMN 列名 VARCHAR(40)- -添加主键约束 alter table

SQL Server将一列的多行内容拼接成一行的实现方法

SQL Server将一列的多行内容拼接成一行的实现方法 投稿:mdxy-dxy 这篇文章主要介绍了SQL Server将一列的多行内容拼接成一行的实现方法,需要的朋友可以参考下 下面大家先看下示例代码: 示例 昨天遇到一个SQL Server的问题:需要写一个储存过程来处理几个表中的数据,最后问题出在我想将一个表的一个列的多行内容拼接成一行,比如表中有两列数据 : 类别 名称 AAA 企业1 AAA 企业2 AAA 企业3 BBB 企业4 BBB 企业5 我想把这个表变成如下格式: 类别 名称

获取SQL中某一列的类型及精度

SELECT @type=t.name, @prec=c.prec FROM sysobjects o        JOIN syscolumns c on o.id=c.id        JOIN systypes t on c.xusertype=t.xusertype WHERE o.name = @SortTable AND c.name = @SortName 获取SQL中某一列的类型及精度

SQL Server 2014 聚集列存储

SQL Server 自2012以来引入了列存储的概念,至今2016对列存储的支持已经是非常友好了.由于我这边线上环境主要是2014,所以本文是以2014为基础的SQL Server 的列存储的介绍.下面我们主要看一下列存储的发展以及一些原理: 列存储的开发是想要处理超大量数据进行分析计算,于是在SQL Server 2012时,SQL Server 引入了列存储索引,用以显著提供高传统数据仓库类型语句的性能,并在SQL Server 2014中做了进一步加强.列存储会将一个列的数据单独存放在一