利用SQL05特性删除表中重复数据_SQL Server时间:2010-05-01 00:59来源: 作者: 点击:93次-
问题:一个表有自增的ID列,表中有一些记录内容重复,也就是说这些记录除了ID不同之外,其他的信息都相同。 ...
问题:一个表有自增的ID列,表中有一些记录内容重复,也就是说这些记录除了ID不同之外,其他的信息都相同。需要把重复的记录保留一条,剩下的删除。
这种需求一般开发人员都会,我这里写出两个版本。
版本一:由于记录有自增列,所以自增列可以做为记录的唯一标识,由此可见,重复的记录的自增ID是一个递增关系,这里我们可以只保留ID最小的那条记录,其它的全部删除。利用一个嵌套语句就非常容易写出下面的SQL。其中的sname,saddress是记录除了ID外的所有列。
DELETE FROM a
WHERE id NOT IN ( SELECT MIN(id)
FROM a
GROUP BY sname,
saddress )
版本二:充分利用SQL05的几个比较实用的特性。这里先简单说说要用到的几个特性。详细用法可到网上搜索下。
1:ROW_NUMBER,它的作用就是用来生成行号,默认是从1开始。
2:公用表表达式(CTE),我这里并不会利用它的递归,而是用它来简化嵌套查询及对表自身引用功能。CTE的语法如下:
[ WITH <common_table_expression> [ ,n ] ]
<common_table_expression>::=
expression_name [ ( column_name [ ,n ] ) ]
AS
( CTE_query_definition )
说明:1>CTE在某种程序上相当表变量或者临时表的功能。但比起表变量来说它最大的优势是对自
身的引用,CTE语句后面紧跟的select ,update,delete等,操作的结果都会直接反应的实际物理表中。相比临时表,最大优势无非是性能,临时表实际是一张物理存在的表,在对它进行操作时,会产生额外的IO开销以及管理上的开销。
2>CTE语法后面需要直接跟上使用CTE的相关语句select ,update,delete等,否则CTE会失效,下面的语句是错误的:
代码
WITH b AS ( SELECT ROW_NUMBER() OVER ( PARTITION BY sname, saddress ORDER BY sname, saddress ) AS rn,
*
FROM a
)
DELETE FROM b
WHERE rn > 1
SELECT * from a
SELECT * FROM b WHERE rn>1
3:PARTITION BY,
分区函数。和聚合函数不同的地方在于它能返回一个分组中的多条记录,聚合函数一般只有一条反映统计值的记录,partition by用于给结果集分组,如果没有指定那么它把整个结果集作为一个分组 。
经过上面的三个关键字的介绍后,下面给出三者相结合后的结果。
代码
WITH b AS ( SELECT ROW_NUMBER() OVER ( PARTITION BY sname, saddress ORDER BY sname, saddress ) AS rn,
*
FROM a
)
DELETE FROM b
WHERE rn > 1
版本一和版本二比较:
1:版本二更加容易阅读。
2:版本二性能较版本一强。我们可以通过以以信息来看。可以看到版本一会发生两次表扫描。
代码
Table 'a'. Scan count 2, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(0 row(s) affected)
Table 'a'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0,
lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(0 row(s) affected)(责任编辑:admin)
-----------------
SQL Server中删除重复数据的几个方法
数据库的使用过程中由于程序方面的问题有时候会碰到重复数据,重复数据导致了数据库部分设置不能正确设置……
方法一
declare @max integer,@id integer
declare cur_rows cursor local for select 主字段,count(*) from 表名 group by 主字段 having count(*) > 1
open cur_rows
fetch cur_rows into @id,@max
while @@fetch_status=0
begin
select @max = @max -1
set rowcount @max
delete from 表名 where 主字段 = @id
fetch cur_rows into @id,@max
end
close cur_rows
set rowcount 0
方法二
有两个意义上的重复记录,一是完全重复的记录,也即所有字段均重复的记录,二是部分关键字段重复的记录,比如Name字段重复,而其他字段不一定重复或都重复可以忽略。
1、对于第一种重复,比较容易解决,使用
select distinct * from tableName
就可以得到无重复记录的结果集。
如果该表需要删除重复的记录(重复记录保留1条),可以按以下方法删除
select distinct * into #Tmp from tableName
drop table tableName
select * into tableName from #Tmp
drop table #Tmp
发生这种重
复的原因是表设计不周产生的,增加唯一索引列即可解决。
2、这类重复问题通常要求保留重复记录中的第一条记录,操作方法如下
假设有重复的字段为Name,Address,要求得到这两个字段唯一的结果集
select identity(int,1,1) as autoID, * into #Tmp from tableName
select min(autoID) as autoID into #Tmp2 from #Tmp group by Name,autoID
select * from #Tmp where autoID in(select autoID from #tmp2)
最后一个select即得到了Name,Address不重复的结果集(但多了一个autoID字段,实际写时可以写在select子句中省去此列)
如何禁止远程访问sql server
(1)SqlServer服务使用两个端口:TCP-1433、UDP-1434。其中1433用于供SqlServer对外提供服务,1434用于向请求者返回SqlServer使用了那(1)SqlServer服务使用两个端口:TCP-1433、UDP-1434。其中1433用于供SqlServer对外提供服务,1434用于向请求者返回SqlServer使用了那个TCP/IP端口。
可以使用SQL Server的企业管理器更改SqlServer的默认TCP端口。方法
a、打开企业管理器,依次选择左侧工具栏的“Microsoft SQL Servers SQL Server组”,打开“SQL实例”(实际环境中为要修改的SQL Server名称)的属性对话框,“常规”选项卡的最下方的“网络配置(N)”按钮,就可以打开“SQL Server 网络使用工具”对话框。
b、在“启用的协议”列表里有TCP/IP协议,在属性里的默认端口选项中输入要修改的端口号即可修改。还有一项为隐藏,如果选中则表示着客户端无法通过枚举服务器来看到这台服务器,起到保护的作用,而且不影响连接。
(2)SqlAgent服务使用TCP-1625、TCP-1640端口提供服务。
(3)SQL 查询分析器,通过1601端口1433,连接SqlServer
-------------
如何禁止向数据库中输入重复内容?新手向你致敬
请教各位老师:
用户在向数据库中各字段添加信息时候,如果库中不存在相同信息则可以添加,如果已经存在则提示不允许重复,请给出具体代码(sql,vb)指点迷津,跪谢。
在应用程序里判断嘛,插入数据之前,判断一下不就是了!
或者给这些字段加唯一索引,insert重复的数据时就会报错
rs.open "select * from tablename where fieldname= ' " & text1 & " ' ",cn
if rs.eof then
msgbox "没有重复 "
else
msgbox "重复了。 "
end if
--创建一个存储过程
create proc 插入
@字段1 varchar(10),@字段2 varchar(10),@flag char(1) output
as
if exists(select 1 from 表 where 字段1=@字段1 and 字段2=@字段2)
begin
set @flag= '0 '
return
end
else
begin
set @flag= '1 '
insert into 表(字段1,字段2) se
lect @字段1,@字段2
return
end
--然后在前台调用该存储过程,将要插入数据库的字段值分别赋值给两个输入参数,并返回另----外一个输出参数,如果输出参数的值为 '0 ',表示有重复记录,插入失败,否则插入成功
----------
检验输入数据是否重复函数(SQL Server)时间:2010-07-18 21:26:40来源:网络 作者:未知 点击:130次 // 检验输入数据是否重复函数(SQL Server)
public bool GetVerifyData(string MySQL)
{
// 数据库SQL语句
string strSQL = @MySQL.Trim().ToString();
// 数据库连接参数(对客户端应用程
// 检验输入数据是否重复函数(SQL Server)
public bool GetVerifyData(string MySQL)
{
// 数据库SQL语句
string strSQL = @MySQL.Trim().ToString();
// 数据库连接参数(对客户端应用程序配置文件的访问)
string strConn = @ConfigurationManager.ConnectionStrings["MyConnectionString"].ConnectionString;
// 创建连接数据库的一个打开连接
SqlConnection MyConn = new SqlConnection(strConn);
try // 正常运行
{
// 使用 ConnectionString 所指定的属性设置打开数据库连接
MyConn.Open();
// 要对数据库执行的一个SQL语句或存储过程
SqlCommand MyComm = new SqlCommand(strSQL, MyConn);
// 提供一种从数据库读取只进的行流的一种方式
SqlDataReader MyReader = MyComm.ExecuteReader();
// 读取数据,判断是否有数据
if (MyReader.HasRows)
{
Console.Write("<script language=JavaScript>");
Console.Write("alert('系统提示:您输入的资料已经存在,请核对后重新输入!');");
Console.Write("</script>");
if ((MyReader != null) & (MyReader.IsClosed!=true))
{
// 关闭
MyReader.Close();
}
// 返回失败
return false;
}
else
{
if ((MyReader != null) & (MyReader.IsClosed!=true))
{
// 关闭
MyReader.Close();
}
// 返回成功
return true;
}
}
catch (SqlException) // 数据库操作异常处理
{
Console.Write("<script language=JavaScript>");
Console.Write("alert('系统提示:当前数据库操作失败或网络忙,请稍后再试!');");
Console.Write("</script>");
if (MyConn.State == ConnectionState.Open)
{
// 关闭数据库连接
MyConn.Close();
}
mysql删除重复的数据保留一条// 返回失败
return false;
}
catch // 异常处理
{
if (MyConn.State == ConnectionState.Open)
{
// 关闭数据库连接
MyConn.Close();
}
// 返回失败
return false;
}
finally // 执行完毕清除在try块中分配的任何资源
{
if (MyConn.State == ConnectionState.Open)
{
// 关闭数据库连接
MyConn.Close();
}
}
}
本篇文章来源于:开发学院 depub 原文链接:depub/2010/0718/24324.php
-----------------
在SQL Server中快速删除重复记录
===========================================================
作者: sqlserver(sqlserver.itpub)
发表于: 2006.07.17 21:53
分类: 一般分类
出处: sqlserver.itpub/post/20961/146559
---------------------------------------------------------------
开发人员的噩梦——删除重复记录
想必每一位开发人员都有过类似的经历,在对数据库进行查询或统计的时候不时地会碰到由于表中存在重复的记录而导致查询和统计结果不准确。解决该问题的办法就是将这些重复的记录删除,只保留其中的一条。
在SQL Server中除了对拥有十几条记录的表进行人工删除外,实现删除重复记录一般都是写一段代码,用游标的方法一行一行检查,删除重复的记录。因为这种方法需要对整个表进行遍历,所以对于
表中的记录数不是很大的时候还是可行的,如果一张表的数据达到上百万条,用游标的方法来删除简直是个噩梦,因为它会执行相当长的一段时间。
四板斧——轻松消除重复记录
殊不知在SQL Server中有一种更为简单的方法,它不需要用游标,只要写一句简单插入语句就能实现删除重复记录的功能。为了能清楚地表述,我们首先假设存在一个产品信息表Products,其表结构如下:
CREATE TABLE Products (
ProductID int,
ProductName nvarchar (40),
Unit char(2),
UnitPrice money
)
假设产品Chang和Tofu的记录在产品信息表中存在重复。现在要删除这些重复的记录,只保留其中的一条。步骤如下:
第一板斧——建立一张具有相同结构的临时表
CREATE TABLE Products_temp (
ProductID int,
ProductName nvarchar (40),
Unit char(2),
UnitPrice money
)
第二板斧——为该表加上索引,并使其忽略重复的值
方法是在企业管理器中到上面建立的临时表Products _temp,单击鼠标右键,选择所有任务,选择管理索引,选择新建。然后设置索引选项。
第三板斧——拷贝产品信息到临时表
insert into Products_temp Select * from Products
此时SQL Server会返回
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论