菜鸟去重复之Sql
前言
本文主要是总结平时工作学习中遇到的使用Sql Server的去除重复的心得体会。
由于平时工作使用Sql并不多,此次在写本文的测试过程中,就遇到了问题,如能有幸得到高手点播,将不胜感激。
高手可以直接看个开头,直接跳过文章内容,点到后面的遇到的问题,辛苦!
准备
本文使用的工具是SQL SERVER 2008,使用的是微软的案例Northwind,选取的数据集以Products表的前10条数据为例,如下图:

Distinct
根据之后紧跟关键字distinct后的字段去除重复,而distinct只能放在所有要查询字段的前面。distinct后的字段有一个不一样即为不同。
示例:根据SupplierID,CategoryID去除重复的内容

Select distinct a.SupplierID,a.CategoryID from (SELECT TOP 10 [ProductID]
,[ProductName]
,[SupplierID]
,[CategoryID]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM [Northwind].[dbo].[Products]) a
获得结果:

Group by
指定由查询 (SELECT) 表达式返回的对象要分入的组。使用group by时可以巧妙地使用聚合函数达到去除重复的目的。
Select Max(a.ProductID) as ID,a.CategoryID ,a.SupplierID from (SELECT TOP 10 [ProductID]
,[ProductName]
,[SupplierID]
,[CategoryID]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM [Northwind].[dbo].[Products]) a
group by a.CategoryID ,a.SupplierID
获得结果:

这次可以获得去除重复过程中ID最大(获取ID最小列可以使用Min函数)的数据行,有了ID唯一标识列就可以解决上面distinct遗留下来的问题。
内联原来的表就可以获取想要的任意字段的值了。
顺带附上Min函数的结果:

Row_Number() over()
over()里面有两个参数
Partition by value_expression
将 FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。 value_expression 指定对结果集进行分区所依据的列。 如果未指定 PARTITION BY,则此函数将查询结果集的所有行视为单个组。
Select a.ProductID,a.SupplierID,a.CategoryID, ROW_NUMBER() over(partition by CategoryID ,SupplierID order by ProductID)as RowN from (
SELECT TOP 10 [ProductID]
,[ProductName]
,[SupplierID]
,[CategoryID]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM [Northwind].[dbo].[Products]) a
获得结果:

Note:此处的数据稍微有点问题,最后会说到。
此次并没有达到去除重复的结果,但稍微看下就发现了多了一行RowN。
这个是根据SupplierID,CategoryID分区并根据ProductID升序获得的行号。所以去除重复也就非常容易了。
Select* from (
Select a.ProductID,a.SupplierID,a.CategoryID, ROW_NUMBER() over(partition by CategoryID ,SupplierID order by ProductID)as RowN from (
SELECT TOP 10 [ProductID]
,[ProductName]
,[SupplierID]
,[CategoryID]
,[QuantityPerUnit]
,[UnitPrice]
,[UnitsInStock]
,[UnitsOnOrder]
,[ReorderLevel]
,[Discontinued]
FROM [Northwind].[dbo].[Products]) a) b where b.RowN=1
获得结果:

顺带附上b.RowN=2结果:

面试问题
取出某年某月每一天的记录的第一条
姑且认为每天第一条记录是当天ID最小的那条,以下为测试使用数据集
SELECT [OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
FROM [Northwind].[dbo].[Orders]
where DATEPART(YEAR,OrderDate)=1997 AND DATEPART(MONTH,OrderDate)=1

方法一:Group by
with Dataset as (SELECT [OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
FROM [Northwind].[dbo].[Orders]
where DATEPART(YEAR,OrderDate)=1997 AND DATEPART(MONTH,OrderDate)=1)
Select a.* from Dataset a,
(SELECT Min([OrderID]) as ID
,DATEPART(DAYOFYEAR,OrderDate) as dayofOrder
FROM [Northwind].[dbo].[Orders]
where DATEPART(YEAR,OrderDate)=1997 AND DATEPART(MONTH,OrderDate)=1
group by DATEPART(DAYOFYEAR,OrderDate)) b
where a.OrderID=b.ID
获得结果:

方法二:Row_Number() over()
with Dataset as (SELECT [OrderID]
,[CustomerID]
,[EmployeeID]
,[OrderDate]
FROM [Northwind].[dbo].[Orders]
where DATEPART(YEAR,OrderDate)=1997 AND DATEPART(MONTH,OrderDate)=1)
select a.* from(Select *,ROW_NUMBER() over(Partition by DatePart(dayofyear,OrderDate)
order by OrderID) as RowN from Dataset) a where a.RowN=1
获得结果:

小结:从以上两种方法可以明显感觉到第二种方法的优势,更强的灵活性,可以获得每天的第二条甚至更多,而且Order by排序有更多选择。
总结
本次关于Sql去除重复的总结就写完了,如果大家还有其他好的方法,还请分享出来。
文中如有错误或者描述不当的地方,还请指出!谢谢!
如有兴趣,继续看下面的问题,帮忙解决了,我将不胜感激!
参考资料:http://stackoverflow.com/questions/3800551/select-first-row-in-each-group-by-group
怪异的问题
测试过程中发现看下图:

这里面的获取的数据明显不是我想要的数据(可以参照准备里的数据集),我测试其他字段都没有问题,只有单独获取CategoryID字段的时候有问题,求高手指点。
附:测试数据库下载
菜鸟去重复之Sql的更多相关文章
- (转)菜鸟去重复之Sql
原文地址:http://www.cnblogs.com/fatbird/p/Sql-Remove-duplicate.html 前言 本文主要是总结平时工作学习中遇到的使用Sql Server的去除重 ...
- 去重复的sql(Oracle)
1.利用group by 去重复 2.可以利用下面的sql去重复,如下 1) select id,name,sex from (select a.*,row_number() over(partiti ...
- 关系数据库SQL之高级数据查询:去重复、组合查询、连接查询、虚拟表
前言 接上一篇关系数据库SQL之基本数据查询:子查询.分组查询.模糊查询,主要是关系型数据库基本数据查询.包括子查询.分组查询.聚合函数查询.模糊查询,本文是介绍一下关系型数据库几种高级数据查询SQL ...
- mysql数据库去重复
参考:http://www.cnblogs.com/duanjie/archive/2011/08/13/2136862.html 说到去重复,感觉逻辑很简单.但动手写起来却并不是那么容易.面试的时候 ...
- paip.输入法编程---带ord gudin去重复-
paip.输入法编程---带ord gudin去重复- 作者Attilax , EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blog.csdn.n ...
- ASP.Net【如何合并DataTable,并且去重复方法】
虽然DataTable.Merge可以很好的实现,但以下代码写出来更好理解 DataTable DataTable1 = new DataTable(); DataTable DataTable2 = ...
- Oracle单表去重复(二)
Oracle单表去重 去重有两层含义,一:是记录完全一样.二:是符合一定条件的认为是重复. 根据表的数量,去重可划分为:单表去重和多表关联去重. 对于去重,一般最容易想到的是用distinct,而 ...
- 写了个去重复文件的 PHP 脚本,
写了个去重复文件的 PHP 脚本点击打开链接 把各个零散网盘.邮箱和服务器上的文件,三台电脑上的文件收集在新硬盘里,然后清空了网络和电脑上的文件.才发现这个文件不能这里放点,那里存点,到时候不知道在哪 ...
- 【知识库】-数据库_MySQL之高级数据查询:去重复、组合查询、连接查询、虚拟表
简书作者:seay 文章出处: 关系数据库SQL之高级数据查询:去重复.组合查询.连接查询.虚拟表 回顾:[知识库]-数据库_MySQL之基本数据查询:子查询.分组查询.模糊查询 Learn [已经过 ...
随机推荐
- scrollWidth,clientWidth,offsetWidth的区别 ---转载的
转载自博客:http://www.cnblogs.com/kongxianghai/p/4192032.html 通过一个demo测试这三个属性的差别. 说明: scrollWidth:对象的实际内容 ...
- java web 程序---注册页面核心代码哈希Map
收获:在运行程序的时候,错误出现.主要是map没有进行判断,是否为空,如果为空,则创建一个对象new HashMap(); 然后就注意细节, String name=request.getParame ...
- Python基础之文件
输出一行一行的,效率更高 一个任务: 主函数:
- TensorFlow计算图,张量,会话基础知识
import tensorflow as tf get_default_graph = "tensorflow_get_default_graph.png" # 当前默认的计算图 ...
- python值解析excel
原文:http://blog.csdn.net/tomatoandbeef/article/details/52253578 一.安装python和xlrd模块 python下载地址,安装好后要配置环 ...
- Hadoop详细安装配置过程
步骤一:基础环境搭建 1.下载并安装ubuntukylin-15.10-desktop-amd64.iso 2.安装ssh sudo apt-get install openssh-server op ...
- 用 Vue 改造 Bootstrap,渐进提升项目框架
前言 Vue 横空出世,以迅雷不及掩耳之势横扫前端界,俨然有当年 jQuery 之势.我认为 Vue 成功的关键在于三点: 学习曲线平缓,有点经验的前端基本上一天就能看完文档,然后就可以上手操作. 上 ...
- sqlserver查询存储过程的创建时间及最后修改时间
select [name] ,create_date ,modify_date FROM sys.all_objects where type_desc = N'SQL_STORED_PROCE ...
- mybatis整合spring的完整过程
1.1 整合思路 1.SqlSessionFactory对象应该放到spring容器中作为单例存在. 2.传统dao的开发方式中,应该从spring容器中获得sqlsession对象. 3.Mappe ...
- zookeeper的ZAB协议
ZAB协议概述 ZooKeeper并没有完全采用Paxos算法,而是使用了一种称为ZooKeeper Atomic Broadcast(ZAB,zookeeper原子消息广播协议)的协议作为其数据一致 ...