sql不重复的查找统计数据

本文介绍了SQL中去除重复数据的方法,包括使用DISTINCT关键字和GROUP BY子句,并通过具体例子展示了如何查询不重复的记录及统计数量。

例表如下:

表名:MYTEST

TID    COL1    COL2     COL3

1           1           A            A
2           1           A            A
3           2           A            A
4           2           B            A
5           3           B            B
6           3           B            B
7           4           C            B
8           4           C            B
9           1           A            A
10         2           B            A

1、查找表中的一个字段,重复的只找一个:

SELECT DISTINCT COL1 FROM MYTEST;

结果为:
1
2
3
4

2、查找表中的多个字段,其中某个字段不重复:

SELECT * FROM MYTEST WHERE rowid IN (SELECT    min(rowid) FROM MYTEST GROUP BY COL1);

结果为:
1           1           A            A
3           2           A            A
5           3           B            B
7           4           C            B

其中rowid为oracle中的虚拟column用来指向表中一个row的存放地址,改为其它的不能运行。(这样理解不知对不对?哪位朋友有更好的理解请给我留言。)

min方法若改为max时结果如下:
6          3          B          B
8          4          C          B
9          1          A          A
10        2          B          A

3、查询并统计该字段的数量。

SELECT COL1,COUNT(COL1) FROM MYTEST GROUP BY COL1;

结果为:
1          3
2          3
3          2
4          2

GROUP BY 哪个字段只能查找哪个字段和该字段的数量。若要同时搜索其它字段就报错。
即:
语句若改成    SELECT COL2,COUNT(COL1) FROM MYTEST GROUP BY COL1;
或    SELECT COL1,COL2,COUNT(COL1) FROM MYTEST GROUP BY COL1;就会报错。

原因可能是:搜索的结果是一组组的数据。在每一组数据中,COL2有很多,所以不能搜索出唯一的一个值。。(这样理解不知对不对?哪位朋友有更好的理解请给我留言。)

4、从两个表中查询并统计数据

表T_OVERTIME字段
int tid = 0;//加班代码
float days = 0;//工日数

表T_OVERTIMEPERSONNEL字段
int tid = 0;//加班人员代码
int overtimeid = 0;//加班代码
int userid=0;//用户ID

统计每个用户的加班工日数
SELECT b.userid,SUM(a.days) FROM T_OVERTIME a,T_OVERTIMEPERSONNEL b WHERE a.tid=b.overtimeid GROUP BY b.userid

以上是在oracle数据库中测试的结果。在其它数据库中不知是否能运行。欢迎大家提供更好更通用的方法。

5、按多个字段分组并统计

SELECT COL1, COL2, COUNT(*) AS Expr1
FROM mytest
GROUP BY COL1, COL2

结果为:

COL1    COL2    COUNT

     1           A           3
     2           A           1
     2          B           2
     3           B           2
     4           C           2
即按COL1, COL2分组后COL1, COL2的内容和每组中记录的数量。

若:SELECT COL1, COL2, COUNT(DISTINCT COL3) AS Expr1
FROM mytest
GROUP BY COL1, COL2

结果为:
COL1    COL2    COUNT
     1           A           1
     2           A           1
     2          B           1
     3           B           1
     4           C           1
若将第7条记录改为 7           4           C           C
则结果为:
COL1    COL2    COUNT
     1           A           1
     2           A           1
     2          B           1
     3           B           1
     4           C           2
即按COL1, COL2分组后COL1, COL2的内容和每组中COL3不重复的记录数。

 

 

使用 DISTINCT 消除重复项
DISTINCT 关键字可从 SELECT 语句的结果中除去重复的行。如果没有指定 DISTINCT,那么将返回所有行,包括重复的行。例如,如果在 titleauthor 中选择所有作者 ID 时未使用 DISTINCT,那么将会返回下列行(其中包括一些重复的行):

USE pubs
SELECT au_id
FROM titleauthor

下面是结果集:

au_id        
-----------  
172-32-1176  
213-46-8915  
213-46-8915  
238-95-7766  
267-41-2394  
267-41-2394  
274-80-9391  
409-56-7008  
427-17-2319  
472-27-2349  
486-29-1786  
486-29-1786  
648-92-1872  
672-71-3249  
712-45-1867  
722-51-5454  
724-80-9391  
724-80-9391  
756-30-7391  
807-91-6654  
846-92-7186  
899-46-2035  
899-46-2035  
998-72-3567  
998-72-3567  

(25 row(s) affected)

而使用了 DISTINCT 后,就能够除去重复项,而只查看唯一的作者 ID:

USE pubs
SELECT DISTINCT au_id
FROM titleauthor

下面是结果集:

au_id        
-----------  
172-32-1176  
213-46-8915  
238-95-7766  
267-41-2394  
274-80-9391  
409-56-7008  
427-17-2319  
472-27-2349  
486-29-1786  
648-92-1872  
672-71-3249  
712-45-1867  
722-51-5454  
724-80-9391  
756-30-7391  
807-91-6654  
846-92-7186  
899-46-2035  
998-72-3567  

(19 row(s) affected)

这是SQL的说明,但是只要表中如果存在Text、ntext、image类型字段时,需要进行查询时,就会出现“不能以DISTINCT方式选择Text、ntext、image数据类型”
不知道怎么去解决这个问题?
使用 DISTINCT 消除重复项
DISTINCT 关键字可从 SELECT 语句的结果中除去重复的行。如果没有指定 DISTINCT,那么将返回所有行,包括重复的行。例如,如果在 titleauthor 中选择所有作者 ID 时未使用 DISTINCT,那么将会返回下列行(其中包括一些重复的行):

USE pubs
SELECT au_id
FROM titleauthor

下面是结果集:

au_id        
-----------  
172-32-1176  
213-46-8915  
213-46-8915  
238-95-7766  
267-41-2394  
267-41-2394  
274-80-9391  
409-56-7008  
427-17-2319  
472-27-2349  
486-29-1786  
486-29-1786  
648-92-1872  
672-71-3249  
712-45-1867  
722-51-5454  
724-80-9391  
724-80-9391  
756-30-7391  
807-91-6654  
846-92-7186  
899-46-2035  
899-46-2035  
998-72-3567  
998-72-3567  

(25 row(s) affected)

而使用了 DISTINCT 后,就能够除去重复项,而只查看唯一的作者 ID:

USE pubs
SELECT DISTINCT au_id
FROM titleauthor

下面是结果集:

au_id        
-----------  
172-32-1176  
213-46-8915  
238-95-7766  
267-41-2394  
274-80-9391  
409-56-7008  
427-17-2319  
472-27-2349  
486-29-1786  
648-92-1872  
672-71-3249  
712-45-1867  
722-51-5454  
724-80-9391  
756-30-7391  
807-91-6654  
846-92-7186  
899-46-2035  
998-72-3567  

(19 row(s) affected)

这是SQL的说明,但是只要表中如果存在Text、ntext、image类型字段时,需要进行查询时,就会出现“不能以DISTINCT方式选择Text、ntext、image数据类型”
不知道怎么去解决这个问题?

 
<think>好的,我现在需要回答用户关于SQL查询重复记录的方法和示例的问题。用户已经提供了一些参考资料,我需要结合这些资料来生成一个结构清晰的中文回答,并符合格式要求,比如使用正确的LaTeX语法,生成相关问题等。 首先,我得确认用户的需求是什么。用户想了解在SQL中如何定位重复值,特别是具体的查询方法和示例语句。根据提供的引用资料,引用[1]提到使用查询语句找出重复记录,而引用[2]则提到了四种方法,包括GROUP BY和HAVING子句,以及窗口函数ROW_NUMBER()的方法。 接下来,我需要整理这些方法,并给出相应的示例。根据引用[2],第一种方法是使用GROUP BY和HAVING,这适用于大多数SQL数据库,比如MySQL、PostgreSQL等。这种方法的基本思路是按照需要检查重复的字段分组,然后筛选出计数大于1的组。例如,查找employees表中first_name和last_name重复的记录,可以使用: SELECT first_name, last_name, COUNT(*) FROM employees GROUP BY first_name, last_name HAVING COUNT(*) > 1; 然后,用户可能需要具体的重复记录详情,这时候可以使用子查询或者JOIN来获取所有重复的行。例如: SELECT * FROM employees WHERE (first_name, last_name) IN ( SELECT first_name, last_name FROM employees GROUP BY first_name, last_name HAVING COUNT(*) > 1 ); 过,引用[2]还提到使用窗口函数ROW_NUMBER(),这在需要处理复杂情况或需要标记重复项时很有用。比如,给每个重复组内的记录编号,然后选择编号大于1的记录: WITH cte AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY first_name, last_name ORDER BY id) AS rn FROM employees ) SELECT * FROM cte WHERE rn > 1; 这种方法在SQL Server、PostgreSQLOracle中适用,可能适用于MySQL的旧版本,但MySQL 8.0+支持窗口函数。 此外,引用[1]提到了MySQL中删除重复记录的方法,但用户的问题主要是查询,所以可能需要详细展开删除部分,但可以简要提及作为补充。 在整理这些方法时,需要确保每个示例的SQL语法正确,并符合用户提供的引用内容。同时,注意使用正确的LaTeX格式,例如变量和代码块要正确标注。比如,代码部分需要用反引号包裹,并标明语言为sql。 然后,生成相关问题。根据用户提供的示例,问题可能涉及同方法的比较、性能优化、适用场景等。例如: 1. GROUP BY和窗口函数在查找重复数据时的效率差异? 2. 如何根据业务需求选择同的重复数据处理方式? 3. 在MySQL中如何实现基于多个字段的重复记录删除? 最后,需要检查回答是否符合所有系统级指令,包括正确的中文表达、LaTeX格式、引用标识的位置,以及相关问题的生成。确保没有使用用户可见的指令,结构清晰,分点说明,代码示例正确,并且相关问题与主题紧密相关。</think>### SQL查询重复记录的方法及示例 在SQL查找重复记录通常涉及**分组统计**或**窗口函数**,以下是具体方法及示例: --- #### 方法1:使用`GROUP BY`和`HAVING`子句 通过分组统计重复次数,筛选出重复组。 ```sql -- 查询重复字段及重复次数 SELECT column1, column2, COUNT(*) AS duplicate_count FROM table_name GROUP BY column1, column2 HAVING COUNT(*) > 1; ``` **示例**:查找`employees`表中`first_name`和`last_name`重复的记录 ```sql SELECT first_name, last_name, COUNT(*) FROM employees GROUP BY first_name, last_name HAVING COUNT(*) > 1; -- 输出重复字段及重复次数[^2] ``` --- #### 方法2:通过子查询获取所有重复行 若需查看重复记录的完整信息,可结合`IN`或`JOIN`: ```sql -- 查询所有重复记录的详细信息 SELECT * FROM table_name WHERE (column1, column2) IN ( SELECT column1, column2 FROM table_name GROUP BY column1, column2 HAVING COUNT(*) > 1 ); ``` --- #### 方法3:使用窗口函数(高级场景) 通过`ROW_NUMBER()`为重复记录标记序号,适用于复杂去重逻辑: ```sql -- 标记重复记录并筛选 WITH cte AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY column1, column2 ORDER BY id -- 按id排序,保留第一条 ) AS rn FROM table_name ) SELECT * FROM cte WHERE rn > 1; -- 输出所有重复行[^2] ``` **适用场景**:需保留最新/最旧记录时,调整`ORDER BY`即可。 --- #### 方法4:通过`EXISTS`关联自身表 ```sql -- 查找重复记录(保留一条) SELECT * FROM table_name t1 WHERE EXISTS ( SELECT 1 FROM table_name t2 WHERE t1.column1 = t2.column1 AND t1.column2 = t2.column2 AND t1.id > t2.id -- 假设id为主键 ); ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值