在CSDN上回贴时,我总是苦口婆心地劝告楼上楼下的朋友们多用联接。可响应甚微。往往一个简单的功能,也一定要写成子查询或游标,弄得非常复杂冗长。的确,这样写对于初学者来说,费力不费脑,思路比较好理解。所以往往得分的也是这些回贴。可事实上,如果你真正熟悉了SQL的编程风格,你会明白,联接查询才是最直接、最清晰、最有力的方法,而更好的办法就是无招胜有招,一条简单查询结束战斗。下面我举几个例子来证明一下这个观点。
例1-1、重复记录的查询和处理
总有一些朋友在网上问,一个表中,有重复的记录,怎么办?当然,一个设计风格良好的关系型数据库,每个表都应该有主键、有唯一索引,所以压根就不该有重复记录。不过有时还是会出现不该出现的事,比如“七.七事变”,比如“9.11”……咳咳,其实我想说的是,有时会有人根本没有数据库的概念,他就不知道主键是什么,或者随意建了一个自动标识的ID列充数(其实这也没什么,没有人天生会设计数据库,关键是愿不愿承认自己的不足并且改进)。更常见的是我们的数据可能来自一些电子表格或文本文件,导入到数据库中时才发现问题。
这里,我们建立一个表,表示某商店的存货。我有意没有加入任何索引和约束,这样,它会很容易地出问题(就像实验室里的裸鼠)。
CREATE TABLE PRODUCT(
ID INT, PNAME CHAR(20),
PRICE MONEY, NUMBER INT,
PDESCRIPTION VARCHAR(50))
现在,我们可以向其中插入一些数据:
IDPNAMEPRICENUMBERPDESCRIPTION
1Apple 123000
1Apple 123000
2Banana 16.997600
3Olive 25.224500
4Orange 15.995500
4Coco Nut 40.992000
5Pineapple 302500
6Olive 25.223000
这里有一些明显的问题,前两行完全一样,这样的重复数据一点意义都没有,只会添乱。InterBase还好点,在它的IBConsole中可以直接修改它们。可在SQL Server中,系统根本无法区分这两行,当我们试图对其中任一行修改时会收到一个错误信息。事实上,这也是一个关系型数据库应有的反应。那我们应该怎么办呢?
事实上,处理它的方法比找出错误数据还简单,联接查询都用不到。用一条SQL语句
SELECT DISTINCT * FROM PRODUCT
就可以把重复数据压缩掉,生成一个包括正常数据的数据集。结果如下:
IDPNAMEPRICENUMBERPDESCRIPTION
1Apple 123000
2Banana 16.997600
3Olive 25.224500
4Orange 15.995500
4Coco Nut 40.992000
5Pineapple 302500
6Olive 25.223000
对于支持SELECT …… INTO……FROM语句的数据库来说,这样一句
SELECT DISTINCT * INTO NewTable FROM PRODUCT
就可把数据导入到一个新表(NewTable )中。或者可以用INERT INTO …… SELECT DISTINCT * FROM ……把它导入到一个现有的表中。总之有了正确的数据集,再如何处理就好办了。相信大家知道这个合并重复数据的关键字DISTINCT后,再不会用游标来处理重复数据了吧。
这是第一步,有时可能我们不想一下把它们压缩掉,而是想先看看到底谁出了问题。好的,用下面的语句可以找出重复的记录,最右边一列“ROW_COUNT”表示这行数据在表中重复的次数:
SELECT ID, PNAME, PRICE, NUMBER, PDESCRIPTION, COUNT(*) ROW_COUNT
FROM PRODUCT
GROUP BY ID, PNAME, PRICE, NUMBER, PDESCRIPTION
HAVING COUNT(*) > 1
IDPNAMEPRICENUMBERPDESCRIPTIONROW_COUNT
1Apple123000NULL2
(所影响的行数为 1 行)
其实就是关键字GROUP BY …… HAVING和统计函数COUNT的一个简单运用,记得在GROUP BY 后面写上完整的字段列表。这表示我们要的是那些完全一致的数据,每个字段都一样。
PRODUCT表中的数据很多时,用前面的方法直接生成正确的数据集效率很低。现在有了这个结果集,我们可以高效率工作了。现在,我们用
SELECT ID, PNAME, PRICE, NUMBER, PDESCRIPTION
FROM PRODUCT
GROUP BY ID, PNAME, PRICE, NUMBER, PDESCRIPTION
HAVING COUNT(*) > 1
把重复的数据生成为一个经过压缩的正确数据集,用前述的方法导出到一个临时表中,然后用
DELETE FROM PRODUCT
WHERE ID IN (
SELECT ID
FROM PRODUCT
GROUP BY ID, PNAME, PRICE, NUMBER, PDESCRIPTION
HAVING COUNT(*) > 1
)
把重复数据从PRODUCT表中删除,再把压缩好的数据插入PRODUCT。现在PRODUCT表中不再有完全重复,不可标识的数据了。
分享到:
相关推荐
"SQL注入简单总结——过滤逗号注入"的主题主要探讨了如何处理那些针对逗号(`,`)进行过滤的SQL注入情况。在SQL语句中,逗号常用于分隔不同的元素,例如在`UNION`、`LIMIT`等子句中。 1. **过滤逗号的绕过方法**: ...
T-SQL性能调优秘籍——基于SQL Server 2012窗口函数,书中提及的网站已经打不开了,在github上找到了。路径在附件中。
总的来说,"图书订购"数据库文件为初学者提供了一个实践SQL Server数据库管理、设计和开发的宝贵平台,涵盖了从基础到进阶的多种知识领域。通过实际操作,你可以加深对数据库系统理解,提升数据库管理技能。
ch07创建SQL Server数据库01——创建数据库
本资源“SQL数据库查询语句基础文本——可复制的查询语句”提供了丰富的SQL语句实例,不仅方便用户直接在数据库中运行,还配以中文解释,帮助理解其工作原理。 1. **基本查询** SQL的基本查询包括`SELECT`语句,...
ch08创建SQL Server数据库02——管理数据库
实验报告的主题聚焦于数据库的简单查询和连接查询,旨在通过SQL Server查询分析器来实践和深化对SQL语言的理解。实验的目的是让学生掌握SQL Server查询分析器的使用,熟悉SQL查询语句,特别是针对数据表的查询操作,...
FOXPRO SQL 未公开特性——别名和自连接 FOXPRO SQL 中的别名和自连接是两个重要的概念。别名是指在 SQL 语句中对数据库文件的另一个名称,自连接则是指在同一个数据库文件中连接不同的记录类型。 在 FOXPRO SQL ...
《SQLServer课程设计——图书馆管理系统》 图书馆管理系统是IT领域中常见的应用实例,它通过数据库技术来管理和维护图书馆的相关信息,如图书、图书类型、读者信息以及借阅情况。在这个系统中,SQLServer作为数据库...
SQL Server 课程设计——图书馆管理系统数据库设计 本文档主要介绍了一个基于 SQL Server 的图书馆管理系统数据库设计,旨在解决传统的人工方式管理图书馆中的混乱和低效问题。该系统主要包括图书、图书类型、借阅...
SQL Server课程设计——图书馆管理系统数据库设计 本资源摘要信息是基于SQL Server课程设计——图书馆管理系统数据库设计的相关知识点,主要涉及到关系型数据库设计、数据模型、数据表结构、数据操作、数据定义语言...
SQL网站注入攻击——明小子工具利用案例 SQL网站注入攻击是一种常见的网络攻击方式,攻击者通过注入恶意SQL代码来获取网站敏感信息或控制网站。明小子工具是SQL网站注入攻击的利器,本文将详细介绍明小子工具的使用...
拨开云雾现真容 SQL语句显神通——宜春市应用计算机开展住房公积金审计纪实.pdf
sql server 数据库——shopsystem
实验报告“贵州大学数据库实验报告——数据库的组合查询和统计查询”主要涵盖了SQL Server查询分析器的使用,以及SQL语言中涉及的查询语句、分组、统计、计算和组合查询的操作方法。以下是对这些知识点的详细说明: ...
本资源"SQL语法大全——中文版"是一份专为初学者设计的指南,旨在帮助用户深入理解并掌握SQL的基本概念和核心语法,从而更好地进行数据查询、更新和管理。 1. **SQL基础** - 数据库概念:SQL用于操作关系型数据库...
【SQL结构化查询语言详解】 SQL(Structured Query Language)是一种用于管理和处理关系数据库的标准语言,它的功能强大,其中聚合分析是统计和分析数据的核心部分。本篇将深入讲解SQL中的聚合函数及其应用。 **...
看完入门篇和进阶篇后,稍加练习,破解...5. 猜解Access时只能用Ascii逐字解码法,SQLServer也可以用这种方法,只需要两者之间的区别即可,但是如果能用SQLServer的报错信息把值暴露出来,那效率和准确率会有极大的提高