`

TSQL中 Count() 函数使用的一点小技巧

阅读更多

 TSQL中 Count() 函数使用的一点小技巧

 

摘自:http://blog.csdn.net/plean/archive/2008/09/08/2900843.aspx

 

阅:使用子查询效率要高于外连接;

 

COUNT( * ) 返回组中项目的数量,这些项目包括 NULL 值和副本。
COUNT(ALL expression) 对组中的每一行都计算 expression 并返回非空值的数量。
COUNT(DISTINCT expression) 对组中的每一行都计算 expression 并返回唯一非空值的数量。
COUNT( expression )  默认是ALL , COUNT( expression ) 其实相当于COUNT(ALL expression);

由于COUNT( * ) 和 COUNT( expression ) 返回的值会不一样,一些情况下就会有问题,比如下面的范例:

有以下两个表
Table1 有以下记录(类似一个分类表)
ID Title
1 aa
2 bb
3 cc
4 dd
5 ee
6 ff
Table2 有以下记录用来记录Table1中的分类具体出现,这里的ID对应Table1中的ID
ID
1
1
2
3
5
3
4


如果我们要统计每一个分类在Table2中的出现次数,(如果某个分类出现次数为0,也要统计出来)
可以用下面的SQL 语句
SELECT count(b.ID) as num ,a.ID as AnswerID
FROM Table1 a left  OUTER JOIN Table2 b ON a.ID = b.ID
group by a.ID

如果是下面的写法,统计出来的结果就是错误的。:

SELECT count(*) as num ,a.ID  as AnswerID
FROM Table1 a left  OUTER JOIN Table2 b ON a.ID = b.ID
group by a.ID 


另外这个统计可以通过下面的方式实现:

SELECT
 CategoryID,
 (SELECT COUNT(*) FROM Content WHERE CategoryID=c.CategoryID)
FROM
 Category c

 

 

 


******************************************************************************

关于子查询和Join的比较


******************************************************************************

 

 

嗯,应该说在某些情况下还是会出现使用JOIN的效率不如使用子查询的情形,至少索引或统计的结构就可能引起这个差异。以Northwind数据库为例,如有下面两个逻辑相等的查询:

SELECT
 c.CategoryID, COUNT(p.CategoryID)
FROM
 Categories c LEFT JOIN Products p
  ON p.CategoryID = c.CategoryID
GROUP BY
 c.CategoryID

和:

SELECT
 c.CategoryID,
 (SELECT COUNT(*) FROM Products
  WHERE CategoryID = c.CategoryID)
FROM
 Categories c

在默认情况下,把两个查询放在一个批里查看执行计划,会发现各自都占50%的开销,而且执行计划完全相同——这就是你说的内部转换。然而,如果把主表(即Categories表)的主键索引删除,情况就不同了——两种查询的执行计划有了微妙的差异,且总是使用子查询的开销要小一些(我曾见过相同逻辑的两种查询开销之比达到7:3甚至更高)。

当然,一个好的DBA不会不给主表主键建立索引,但我想说的是,SQL Server内部对子查询向外连接的转换过程对某些情形来说还是有更好的优化策略的。另外从SQL程序员的角度说,对于这种应用场合应该首先考虑使用子查询,无论从可读性、执行效率还是功能来说,这种写法都有很大的优势。

 

 

 


专家就是专家,一针见血。不过我又确认了一下,发现就算写成这样:

SELECT
 c.CategoryID, COUNT(p.CategoryID)
FROM
 Categories c LEFT JOIN Products p
  ON p.CategoryID = c.CategoryID
GROUP BY
 c.CategoryID

和:

SELECT
 c.CategoryID,
 (SELECT COUNT(*) FROM Products
  WHERE CategoryID = c.CategoryID)
FROM
 Categories c
GROUP BY
 c.CategoryID

在CategoryID字段没有索引的时候,还是使用子查询的开销更小一些——而此时两者的逻辑应该是一样的了。所以结论还是不变,就是在这种应用场合下,使用子查询的性能总是小于等于使用外连接的。而且在CategoryID是主键的前提下,使用子查询的时候可以不用写GROUP BY字句而获得同样的结果,这样可以不受GROUP BY对选择列的局限。

 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/plean/archive/2008/09/08/2900843.aspx

 

分享到:
评论

相关推荐

    plsql和tsql常用函数比对

    - **绝对值**:在PL/SQL中使用`ABS()`函数,如`select abs(-1) value`;T-SQL同样使用`ABS()`函数,如`select abs(-1) value from dual`。 - **取整(大)**:PL/SQL使用`CEIL()`,如`select ceil(-1.001) value ...

    TSQL与PLSQL比较

    - PLSQL: 类似地,使用 `CEIL()` 和 `FLOOR()`,但Oracle中的 `TRUNC()` 函数用于去掉小数部分,如 `SELECT CEIL(-1.001) value FROM DUAL`, `SELECT FLOOR(-1.001) value FROM DUAL`。 3. **四舍五入**: - TSQL...

    PLSQL与TSQL一些语法区别

    PLSQL和TSQL是两种广泛使用的SQL方言,分别在Oracle和Microsoft SQL Server中使用。它们在语法和功能上有许多相似之处,但也存在显著的区别。以下是对这两种语言在数据类型、变量声明与引用、函数与操作符、语句结构...

    TSQL参考实用教程(chm)

    3. **聚合函数**:如COUNT、SUM、AVG、MAX和MIN,用于对一组值进行计算。 4. **窗口函数**:ROW_NUMBER、RANK、DENSE_RANK和LEAD/LAG等,提供了更复杂的数据分析能力。 5. **游标**:允许逐行处理查询结果,适合...

    TSQL 分组集1

    在SQL的世界里,TSQL(Transact-SQL)是Microsoft SQL Server所使用的扩展SQL语言,它包含了许多高级特性,其中之一便是分组集(Grouping Sets)。分组集允许我们在一个查询中实现多维度的分组,这对于数据分析和...

    TSQL语言,数据库

    在TSQL中,IF-ELSE语句的语法与C语言类似,但需要使用BEGIN-END来包裹多条语句。例如,可以使用IF-ELSE来统计班级平均分,并根据平均分决定显示“成绩优秀”还是“成绩较差”,同时显示相应的学员信息。 在实际应用...

    TSQL编程教程及实例

    "TSQL编程3-函数.doc"可能详细讲解了TSQL中的内置函数,如数学函数、字符串函数、日期时间函数等。例如,`LEN()`用于返回字符串长度,`DATEADD()`用于添加或减去日期时间间隔。 4. **TSQL过程** "TSQL编程2-过程....

    TSQL_Programming_20061113

    5. **用户定义函数(UDFs)**:“Chapter 06 - User Defined Functions.sql”涵盖了UDFs的创建和使用,分为标量函数和表值函数,它们可复用性强,简化复杂的计算逻辑。 6. **动态执行(Dynamic Execution)**:...

    sql 入门 tsql 入门

    #### 四、在网站中使用SQL 要在网站上展示数据库中的数据,通常需要以下组件: - **RDBMS**(关系型数据库管理系统),如MS Access, SQL Server, MySQL等。 - **服务器端脚本语言**,如PHP或ASP。 - **SQL**,用于...

    TSQL2012.sql

    TSQL2012数据库脚本下载

    数据库TSQL语言课件

    TSQL(Transact-SQL)是SQL(Structured Query Language)的一个扩展,由Microsoft在其SQL Server数据库管理系统中使用。TSQL不仅包括标准SQL的所有功能,还增加了一些特有的语法和功能,使得它在处理复杂的数据库...

    TSQL编程1-规则.pdf

    - 在T-SQL中,使用 DECLARE 关键字来声明变量,例如 `DECLARE @A CHAR(10)`。 - 数据类型如 `VARCHAR(50)`、`FLOAT` 和 `INT` 分别用于声明字符、浮点数和整数类型的变量。 - SQL Server内置函数和常量如 @@...

    TSQL 存储过程 游标 数据库 sql优化 存储过程分页

    虽然游标在某些场景下是必要的,但通常不推荐在大规模数据操作中使用,因为它们可能降低性能。 【数据库优化】 SQL优化是提高数据库性能的关键,包括: 1. **索引优化**:合理创建索引可以显著加快查询速度。 2. **...

    TSQL 存储过程 和 游标

    存储过程是SQL Server中的一种重要数据库对象,它是预编译的SQL语句集合,可以视为可重复使用的、有名字的批处理。它们解决了批处理语句的两个主要问题:无法传递参数和无法多次调用。存储过程允许用户通过参数传递...

    17.函数整理(T-SQL 版).pdf

    在本文档中,我们将详细探讨在SQL Server使用的T-SQL(Transact-SQL)中,涉及到的函数的整理。这些函数被分为数学函数和字符串函数两大类,并且详细介绍了每个函数的功能以及它们的基本用法。 一、数学函数 1. 求...

    数据库 TSQL程序设计基础PPT学习教案.pptx

    【数据库 TSQL程序设计基础】\n\n数据库技术是IT领域不可或缺的一部分,而TSQL(Transact-SQL)则是微软SQL Server中用于管理和操作数据库的主要编程语言。本篇PPT学习教案将深入介绍TSQL的基础知识,帮助学习者掌握...

    SQLSERVER TSQL 源码

    《SQL SERVER 2008技术内幕:T-SQL语言基础》随书出来的源码。在学习这本书时,一定要在SQLSERVER2008上面创建这个数据库,供实验,一定要多做实验,才能有效掌握SQL语句的编写。

    TSQL编程基础.pdf

    游标允许从结果集中逐行检索数据,文档中虽未详细说明游标使用,但提及了@@CURSOR_ROWS系统函数用于获取当前游标打开的结果集中行的数量。 7. 系统表和系统函数: 文档提到了使用系统表(如sysobjects)和系统函数...

Global site tag (gtag.js) - Google Analytics