首页 > 开发 > 综合 > 正文

读《程序员的SQL金典》[1]--基础数据检索

2024-07-21 02:50:51
字体:
来源:转载
供稿:网友
读《程序员的SQL金典》[1]--基础数据检索

前言

《程序员的SQL金典》这本书是杨中科老师的,拜读了一下,简单做了读书笔记供以后翻阅。仅供学习分享,要想细读的话推荐购买原版呀!

这次读书的时候用了新的办法把看书计划进行了量化,虽然简单,发现还是有效果的。

image


1. Count(*)与Count(column)区别

Count(*)统计结果集总条数;

Count(column)统计结果集中column字段不为null的总条数。

2. 低效的where 1=1

为了实现动态拼接查询条件的功能,有时我们会使用where 1=1这样看似聪明的解决方案。但实际上会造成很大的性能损失,这个条件使得数据库无法使用索引等优化查询策略,数据库会进行全表扫描。当数据量较大的时候查询速度可能会变得很慢。(在SQL Server2012等数据库中,对这种情况其实已经做了优化)

优化前:

PRivate static void CreateWhere(QueryParam param)        {    string where = " where 1=1 " ;    if (param != null )            {    if (param.Haspicture)                {                    where += " AND picture<>'' " ;                }    if (param.ClassId > 0)                {                    where += " AND ClassID=@classid " ;                }    if (param.AuthorId > 0)                {                    where += " AND UserId=@UserId";                }            }        }

可以改用下面的逻辑实现。

private static void CreateWhere1(QueryParam param)        {    StringBuilder where = new StringBuilder( " where 1=1 ");    bool hasWhere = false ;    if (param != null )            {    if (param.HasPicture)                {                    hasWhere = AppendWhereIfNeed(where, hasWhere);                    where.AppendLine( "picture<>'' ");                }    if (param.ClassId > 0)                {                    hasWhere = AppendWhereIfNeed(where, hasWhere);                    where.AppendLine( "ClassID=@classid ");                }    if (param.AuthorId > 0)                {                    hasWhere = AppendWhereIfNeed(where, hasWhere);                    where.AppendLine( "UserId=@UserId");                }            }        }    private static bool AppendWhereIfNeed( StringBuilder where, bool hasWhere)        {    if (hasWhere)            {                where.Append( " and ");            }            else            {                where.Append( " where ");            }    return true ;        }
3.Group By分组

分组查询时,所有SELECT语句中出现的列必须出现在Group By子句中(聚合函数除外。)

实例:

①错误

SELECT FAge ,FSalary FROM T_Employee GROUP BY FAge

--选择列表中的列 'T_Employee.FSalary' 无效,因为该列没有包含在聚合函数或 GROUP BY 子句中。

②正确

SELECT FAge ,Max( FSalary) FROM T_Employee GROUP BY FAge

FAge (无列名)22 1200.0023 5000.0025 8300.0028 6200.00

4.Having 语句

①聚合函数不能出现在where语句中,此时可以使用having语句代替。

SELECT FAge , COUNT(*) AS CountOfThisAge FROM T_EmployeeGROUP BY FAge--WHERE COUNT(*)>1--错误HAVING COUNT (*)> 1--正确

②HAVING子句位置要在GROUP子句之后;

③HAVING子句也可以像where一样使用较复杂的过滤条件

SELECT FAge ,COUNT(*) AS CountOfThisAge FROM T_EmployeeGROUP BY FAgeHAVING COUNT (FAge)= 1 OR COUNT(FAge )=2SELECT FAge ,COUNT(*) AS CountOfThisAge FROM T_EmployeeGROUP BY FAgeHAVING COUNT (FAge) IN(1 ,2)
5.ROW_NUMBER() OVER(排序规则)

ROW_NUMBER()函数可以计算数据的行号。但该函数不能放在WHERE子句中,如果想根据行号进行过滤可以使用子查询来实现。

SELECT * FROM(SELECT ROW_NUMBER () OVER (ORDER BY FSalary DESC) num, FName,FSalaryFROM T_Employee) AWHERE A .num BETWEEN 1 AND 3
6.DISTINCT

DISTINCT是针对这个结果集取消重复的,而不是针对单个列。

7.字符串计算函数

LEN(string)可以计算字段的长度。

SELECT FName ,LEN( FName) AS NameLengthFROM T_EmployeeWHERE FName IS NOT NULL

SUBSTRING(str,start,length):

字符串截取函数。str表示原字符串,start为开始位置(从1开始计算),length为截取的长度。

SELECT FName ,SUBSTRING( FName,1 ,2) AS NameLengthFROM T_EmployeeWHERE FName IS NOT NULL

执行结果:

FName NameLengthTom ToJerry JeJane Ja

8.UNION

UNION可以进行结果集的合并。如果想合并之后自动去掉重复行,可以使用UNION ALL.


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表