针对distinct疑问引发的一系列思考

有人提出了这样一个问题,整理出来给大家也参考一下

假设有如下这样一张表格:

这里的数据,具有如下的特征:在一个DepartmentId中,可能会有多个Name,反之也是一样。就是说Name和DepartmentId是多对多的关系。

现在想实现这样一个查询:按照DepartmentID排完序之后(第一步),再获取Name列的不重复值(第二步),而且要保留在第一步后的相对顺序。以本例而言,应该返回三个值依次是:ACB

我们首先会想到下面这样一个写法

select distinct name from Sample order by DepartmentId

从语义上说,这是很自然的。但是很可惜,这个语句根本无法执行,错误消息是:

这个错误的意思是,如果使用了DISTINCT(去重复值),则出现在OrderBy后面的字段,必须也出现在SELECT后面,但如果DepartmentID如果也真的出现在SELECT后面,显然是不会有重复值的,所以结果肯定也是不对的。

select distinct name,DepartmentId from Sample order by DepartmentId

那么,既然DISINCT 与OrderBy结合起来用会有这个的一个问题,我们是否有可能变通一下,例如下面这样:

SELECT distinct a.Name FROM (select top 100 percent name from Sample order by DepartmentId) a

想比较之前的写法,我们用到了子查询技术。同样从语义上看,仍热是很直观明了的。我想先按照DepartmentId进行排序, 然后再去重复值。但是返回到结果是下面这样的:

虽然确实去除了重复值,但返回的顺序却是不对的。我们希望是先按照DepartmentId排序之后,然后去除重复值,并且保留排序后的相对顺序。

为什么会出现上面这个结果呢?其实是因为DISTINCT本身是会做排序的,而且这个行为是无法更改的(下图的执行计划中可以看到这一点)。所以其实我们之前做的Order by在这里会失去意义。【实际上,如果观察ADO.NET Entity Framework等ORM工具中生成的类似的一个查询,它会自动丢弃Order by的设置】

那么,这样的情况下,是不是就不可能实现需求了呢?虽然说,这个需求并不多见,绝大部分时候,DISTINCT作为最后一个操作,做一次排序是合乎情理的。

我是这样考虑到,既然DISTINCT的这个行为是内置的,那么是否可以绕过这个操作呢?最终我用的一个解决方案是:我能不能把每个Name都编上一个编号,例如有两个A的话,第一个A我为它编号为1,第二个编号为2,以此类推。然后,查询的时候,我先排序,然后筛选那些编号为1的Name,这样其实也就实现了去重复值了。

SQL Server 2005开始提供了一个ROW_NUMBER的功能,结合这个功能,我实现了下面这样的查询:

select a.Name from (select top 100 percent Name,DepartmentId,ROW_NUMBER() over(partition by name order by departmentid) row from Sample order by DepartmentId) a where a.row=1 order by a.DepartmentId

然后,我得到了下面这样的结果,我推敲下来,这应该是符合了之前提到的这个需求的

相比较而言,这个查询的效率会低一些,这个是可以预见的(可以通过下图看出一点端倪)。但如果需求是硬性的,那么牺牲一些性能也是不奇怪的。当然,我们可以再研究看看是否有更优的一些写法。无论如何,使用内置标准的实现,通常都是相对较快的。

以上就是关于distinct疑问引发的一系列思考,希望对大家的学习有所帮助。

时间: 2024-07-30 13:25:34

针对distinct疑问引发的一系列思考的相关文章

针对distinct疑问引发的一系列思考_MsSql

有人提出了这样一个问题,整理出来给大家也参考一下 假设有如下这样一张表格: 这里的数据,具有如下的特征:在一个DepartmentId中,可能会有多个Name,反之也是一样.就是说Name和DepartmentId是多对多的关系. 现在想实现这样一个查询:按照DepartmentID排完序之后(第一步),再获取Name列的不重复值(第二步),而且要保留在第一步后的相对顺序.以本例而言,应该返回三个值依次是:ACB 我们首先会想到下面这样一个写法 select distinct name from

HP主动召回电池引发口碑营销思考

HP主动召回电池引发口碑营销思考 作者:王斌 笔名:磐石之心 今天一大早(2009.5.15)上网就看到各大IT网站头条"惠普主动召回笔记本电池7万块",并且公布了相关产品型号以及召回办法.其实,任何产品都不可能做到零缺陷,无论是电子产品.汽车还是其他,因此产品召回制度和法规变得十分必要. 企业召回存在http://www.aliyun.com/zixun/aggregation/11233.html">安全隐患的产品是责任和义务,不召回或者被强制召回则体现了企业责任感

PYTHON 中使用 GLOBAL引发的一系列问题_python

哪里出问题了 python 中,使用 global 会将全局变量设为本函数可用.同时,在函数内部访问变量会先本地再全局. 在嵌套函数中,使用 global 会产生不合常理的行为. 上代码: In [96]: def x(): b = 12 def y(): global a,b a = 1 b = 2 y() print "b =",b ....: In [97]: a = 111 In [98]: del b In [99]: x() b = 12 In [100]: a Out[1

一张最美毕业照引发的营销思考

中介交易 SEO诊断 淘宝客 云主机 技术大厅 很多人夸雷军是互联网营销专家,说他真能炒作,但雷军说:我们从来认为最好的营销,就是做好产品,做好服务.如果你真的把这件事情做好了,其实其他一切顺理成章.的确,无论是卖手机的小米还是卖煎饼的黄太吉,就营销来说确实是业界楷模,但就产品和服务本身来讲,更是力求将用户体验做到极致的杰出典范.一个个品牌.一场场成功的营销活动正在印证着:互联网时代,产品是最好的营销,体验是最好的服务,口碑是最好的品牌.将产品与品牌营销活动结合,激发粉丝的能动性进而对产品起到促

百度针对SEO行业做出了一系列的举措

摘要: 近日来,百度针对SEO行业做出了一系列的举措.据Admin5站长网消息,3月14日百度启动了3.15专项行动系列中最大力度的网络安全推广行动.届时百度将从3月14日零时起,在首页连续3天发布 近日来,百度针对SEO行业做出了一系列的举措.据Admin5站长网消息,3月14日百度启动了"3.15专项行动"系列中最大力度的网络安全推广行动.届时百度将从3月14日零时起,在首页连续3天发布主题为"打击虚假信息,从这里开始!"的文字链接 .任何访问百度首页的用户,只

百度因打击违规医药引发的一系列口水战

百度因打击违规医药引发的一系列口水战,逐渐进入新的剧情.昨天上午,百度首次向媒体披露著名医疗推广机构"利民时代"多项违规推广及遭百度下线的证据,并称员工过去48小时内遭到多次恐吓. 据一位知情人向记者提供的最新线索,这次风波幕后操盘手正指向医疗行业著名的福建邱氏兄弟.据透露,邱氏兄弟在业内拥有深厚人脉,哥哥邱朝敏为上市公司七彩集团董事长.百度公关部昨证实,承认"利民时代"背后老板的确姓邱. 百度公布证据回应炮轰 本周一,百度宣布对违规医疗推广展开严打,随后引发一系列

一个回车符引发的问题思考

在维护和开发通信类软件产品的过程中,经常需要处理一些软件故障问题.在问题刚出现的时候,大家可能显得手足无措,有一种天都要塌下来的感觉.但在问题原因找到之后,大家又会觉得问题原因非常的简单,要是当初开发的时候仔细一点,是不会犯这样的低级错误的.最近,本人就遇到了一个回车符引发的问题. 近日,在开发某软件版本时需要对文件进行操作,在代码中使用了Linux C语言中的opendir函数,但是该函数始终返回NULL,提示文件路径不存在. 本人查了一下该函数的具体情况.opendir函数的原型为: DIR

由金融服务中的智能机器人技术引发的种种思考

云栖TechDay活动第二十期中,蚂蚁金服人工智能部资深算法专家张家兴带来的分享是<金融服务中的智能机器人技术>.他首先介绍了蚂蚁金融中AI驱动的金融服务,详细讲解了人工智能产品"客服机器人"背后的原理和工作方式.分享中,张家兴谈到了自己对智能机器人的认识,并与在场的听众一起探讨了关于智能机器人技术方面的思考. 以下是现场分享观点整理. AI驱动的金融服务 安全.普惠.绿色是蚂蚁金融的三大目标,也是蚂蚁金服的整个愿景.首先,对安全而言,金融行业必须要有足够的安全保障:其次,

华南虎照片真伪引发事件的思考

&http://www.aliyun.com/zixun/aggregation/37954.html">nbsp;      2007年10月12日,陕西林业厅公布了猎人周正龙用数码相机和胶片相机拍摄的华南虎照片.随后,照片真实性受到来自部分网友.华南虎专家和中科院专家等方面质疑,并引发全国性关注.不管网民还是领导,甚至大到中央级人物都被卷到这场真伪的事件.目前华南虎照片真伪鉴别还在升级, 陕西省林业厅副厅长朱巨龙为证明虎照是真使出绝招:如果周正龙拍的华南虎照片有假,他将第一个主