VBA在处理大量的数据/计算时如果使用常规方法会比较慢,因此需要对其进行性能优化以提高运行速度,一般的方法是数组计算或者sql计算。SQL计算的速度最快,限制也是最多的,数组速度其次,灵活性也更高

如果要在vba中调用sql处理数据基本可以遵循一个套路,只要修改其中的SQL语句即可

调用sql处理数据VBA代码如下,其中’##### #####中的地方是每次运行时要根据情况修改的:

Sub Sql_Query()

 Dim Conn As Object, Rst As Object
Dim strConn As String, strSQL As String
Dim i As Integer, PathStr As String
Set Conn = CreateObject("ADODB.Connection")
Set Rst = CreateObject("ADODB.Recordset")
PathStr = ThisWorkbook.FullName
Select Case Application.Version * 1 '设置连接字符串,根据版本创建连接(不同版本的excel连接是不同的)
Case Is <= 11
strConn = "Provider=Microsoft.Jet.Oledb.4.0;Extended Properties=excel 8.0;Data source=" & PathStr
Case Is >= 12
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & PathStr & ";Extended Properties=""Excel 12.0;HDR=YES"";"""
End Select strSQL = "Select * FROM [rawdata$]" '####在这里改SQL查询语句#### Conn.Open strConn '打开数据库链接
Set Rst = Conn.Execute(strSQL) '执行查询,并将结果输出到记录集对象
With ThisWorkbook.Sheets("sql data") '#####在这里更改输出的位置对应的表名####
.Cells.Clear
For i = 0 To Rst.Fields.Count - 1 '填写标题
.Cells(1, i + 1) = Rst.Fields(i).Name '在第一行输出字段名
Next i
.Range("A2").CopyFromRecordset Rst '从A2单元格开始输出
.Cells.EntireColumn.AutoFit '自动调整列宽
End With
Rst.Close '关闭数据库连接
Conn.Close
Set Conn = Nothing
Set Rst = Nothing End Sub

接下来,开始学习SQL语句语法

1.基于一张工作表的查询语法

SQL语法格式比较固定,只需要根据特定的语法顺序,再根据需求加减关键字即可。首先我们给出一个比较全的格式如下:

 SELECT   [DISTINCT]   [TOP <数值>  [PERCENT]]   列标题  [聚合函数]   [[AS] <别名列标题>]   FROM  表或查询 [[AS] <别名>]   [WHERE <筛选条件>]  [ORDER BY <排序项>  [ASC|DESC]]

说明:

  1. <>表示必选项,[]表示可选项,|表示多选一。
  2. SQL语句中不区分大小写,上述式中的的大写意为SQL中关键字
  3. SELECT 关键字:选取关键字
  4. DISTINCT关键字:去除重复的行
  5. TOP 关键字:显示前几条记录
  6. PERCENT关键字:TOP 与 PERCENT 组合在SQL语句中的使用可以按照百分比提取数据
  7. AS关键字:给标题列重新命一个新名称
  8. FROM关键字:给定数据源的名称
  9. WHERE关键字:筛选条件语句
  10. ORDER BY关键字:排序,一般和ASC|DESC一起使用,将结果升序或者降序排列。

接下来详细讲解每一个关键字的使用:

SELECT关键字和FROM 关键字

SELECT关键字和FROM 关键字是每个SQL语句中都必须要有的关键字。SELECT关键字可以选取最终需要显示所有字段,而FROM关键字则用于告诉程序数据源的位置在哪里。VBA中一个最基本的SQL语句写法如下:

SELECT 列字段名1,列字段名2,列字段名3...... FROM [工作表名称$]

例如我们需要从student这一个sheet中取出ID,name,address,score这四列数据:

select ID,name,address,score from [student$]

也可以使用[]将列名括起来表示这是一个列名

select [ID],[name],[address],[score] from [student$]

如果需要取所有的列,可以直接使用“*”号来取全部的列,从而减少代码量

#*号是代表全部列
select * from [sheet1$]

AS关键字

AS关键字用于给字段或者数据源表取别名,从而简化一些比较长的表名或字段名

#从student表中选取姓名列,并重命名为Name
SELECT 姓名 AS Name FROM [Student$]

DISTINCT关键字

DISTINCT关键字功能是去重,语法结构为:

SELECT DISTINCT 要去重复值的字段1,要去重复值的字段2...... FROM [工作表名$]

举例如下:

#选取所有不重复的name
Select Distinct name From [student$]
#选取name和ID都不重复的数据
Select Distinct name,ID From [student$]

WHERE关键字

where关键字可以按条件筛选数据。WHERE语句后可以有一个或多个条件,条件之间可以用操作符AND 或者OR进行连接。
WHERE语句的语法结构如下:

SELECT 列字段名称 FROM [表名称$] WHERE 条件

where后的条件语句可以是运算符或逻辑判断,包含大于、小于、等于、不等于、大于或等于、小于或等于、IN、 BETWEEN、AND、NOT等。

#选取取消费金额等于100的数据
SELECT * FROM [test$] where 消费金额=100
#选取级别为A的数据
SELECT * FROM [test$] where 级别='A'
#选取级别不为A的数据
SELECT * FROM [test$] where 级别<>'A'
#选取级别为A,B,C,D的数据
SELECT * FROM [test$] where 级别 in ('A','B','C','D')
#选取取消费金额不为空的数据
SELECT * FROM [test$] where 消费金额 is not NULL
#选取取消费金额大于100且级别为A的数据
SELECT * FROM [test$] where 消费金额>100 AND 级别='A'

ORDER BY关键字

ORDER BY关键字可以对结果排序,升序的关键词为ASC,也是默认值,通常不指定。降序为DESC。语法结构如下:

SELECT 列字段名 FROM [工作表名称$] ORDER BY 指定列字段名 升序(降序)

按成绩进行升序排序的SQL语句如下:

Select * FROM [Sheet1$] ORDER BY 成绩 ASC

,如果要按两个或两个以上字段,那么字段与字段之间用号逗隔开,

Top关键字

TOP按顺序提取前n行的记录,语法结构如下:

SELECT TOP 3 * FROM [工作表名$]

如提取成绩前三名的记录

Select top 3 * FROM [Sheet1$A1:C17]  ORDER BY score

其中[Sheet1$A1:C17]这个表示工作表名Sheet1的工作表A1:C17的这个单元格区域,加上了指定的单元格区域为数据。可以根据自己的实际情况,来改变.
不在同一张表上显示结果,而且数据源规范,就可以直接用[工作表名$]。或者书写的时候写上列名不用星号(“*”)
这两个也是和标准sql之间差别较大的地方

TOP 与 PERCENT 组合在SQL语句中的使用可以按照百分比提取数据,例如按成绩降序排列提取前30%

Select TOP 30 PERCENT * FROM [Sheet1$A1:C17]  ORDER BY 成绩 DESC
聚合函数

SQL聚合函数包括sum,count,avg,max,min等,与excel的公式有同样的效果,但是在大数据量的情况下速度会提升很多,而且在多条件求和时会比使用sumifs简单,直观的多
多条件求和的语法结构为:

SELECT 分类字段1, 分类字段2 , SUM(统计字段) as 产品总数 From [Sheet1$] GROUP BY 分类字段1, 分类字段2

例如按照日期和姓名汇总产品数:

SELECT 日期, 姓名, SUM(产品数) as 产品总数 From [Sheet1$] GROUP BY 日期, 姓名

注意事项:
1.在SQL语句中SQL语句英文不区分大小写,但标点符号必须是英文半角状态下输入,字段名也必须跟原来的一样。
2.使用SQL语句的时候,必须避免列字段中使用下面的特殊字符:
空格、双引号(")、撇(')、数字标记(#)、百分号(%)、大于号(>)、小于号(<)、叹号(!)、句号(.)、方括号([或])、星号(*)、美元符号($)、分号(;)、脱字号(^)、圆括号((或))、加号(+)、反斜杠(\或/)。
如果在源数据表的列字段使用了这些特殊字符,那么在使用SQL语句列出各字段的数据时,就会发生错误。为了规范使用SQL语句,在对数据源字段命名时,尽量避免使用这些特殊字符。

日期数据在SQL表达式中的应用

在SQL表达式运算符条件中,要查询日期和时间类型的数据,需要在数据值两端加上井字符号(#)以表示日期类型。
日期可以有多种表示方式,最符合中国人的习惯是“年-月-日”或“年/月/日”的表示方式。也就是说年月日之间的分隔符可以用“-”或“/”。
例如表示2013年10月1日
可以采用以下表达式:

年月日
#2013-10-1#
年日月
#2013-1-10#
年月日
#2013/10/1#
日月年
#1/10/2013/#
月日年
#10/1/2013#
以表达式在系统无错识别最高的应该是
月/日/年
#10/1/2013#
如何查询二个日期间的数据

Where … AND…语句,例如查找大于等于2013年10月1日,小于等于2013年10月7日的数据,的SQL表达式为:

SELECT * From [Sheet1$A:C] where 日期>=#10/1/2013# And 日期<=#10/7/2013#

还可以以单元为动态引用查询两个日期内的数据,如下图所示

 strSQL = "SELECT * From [Sheet1$A:C] where 日期>=#" & Range("J1") & "# And 日期<=#" & Range("K1") & "#"

like关键字

Like 操作符用于在 WHERE 子句中搜索列中的模糊匹配

Select 列字段名 From [工作表名$] Where 列字段 Like '关键字'

可以加上通配符% (相当于函数公式中的通配符*)

strSQL = "Select * from [Sheet1$] Where 姓名 like '[AB]%'"

这一语句表示匹配姓名以A开头或B开头的数据
同样的可以反向查询姓名不以A开头或B开头的数据

strSQL = "Select * from [Sheet1$] Where 姓名 like '[!AB]%'"
--or
strSQL = "Select * from [Sheet1$] Where not 姓名 like '[AB]%'"
in关键字

In运算符允许 在 WHERE 子句中规定多个值,语法如下:

Select 字段 From [表名$] Where 字段 In(条件1, 条件2,条件3, ....)

如果在In的条件中不是数值类型,一定要加上引号。
eg:

Select *  FROM [Sheet1$A:D] where 省份 in('广东','广西')

2.两表的上下拼接

将两表连接起来的语句一般是UNION和UNION ALL
UNION ALL是查询所有记录(直接连接,可以重复),UNION只查询不重复(指整条记录不重复,取唯一)的记录,两种语句如果有重复记录,则查询结果就不一样。
在数据库中,UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同。
UNION在运行时先取出几个表的结果,再用排序空间进行排序删除重复的记录,最后返回结果集,如果表数据量大的话可能会导致用磁盘进行排序。
而UNION ALL只是简单的将两个结果合并后就返回。这样,如果返回的两个结果集中有重复的数据,那么返回的结从效率上说,UNION ALL 要比UNION快很多,所以,如果可以确认合并的两个结果集中不包含重复的数据的话,那么就使用UNION ALL。
例如将sheet1与sheet2中的数据连接起来:

SELECT 日期,姓名,产品数 From [Sheet1$] UNION SELECT 日期,姓名,产品数 From [Sheet2$]

这个是在两张表的格式一样的情况下直接连接,但是有些情况下两表的格式并不一样,这个时候可以使用下列语句:
例如sheet1中有日期,姓名两个字段,而sheet2中有姓名,产品数两个字段,需要上下连接两个表格:

SELECT 日期,姓名,null as 产品数 From [Sheet1$] UNION SELECT null as 日期,姓名,产品数 From [Sheet2$]

即使用null加列拼成格式相同的两个表格再连接

3.两表的左右连接

两表的左右连接即是join关键字
SQL代替Vlookup 精确查找(左连接 “Left Outer JOIN” 用法),语法结构为:

Select 表名 .字段1,表名 .字段2,表名 .字段3,表名 .字段4 FROM 查询表 AS 别名1  Left Outer JOIN 被查询表 AS 别名2 ON  别名1.字段名=别名2.字段名

例如:

SELECT A.姓名,B.性别,B.部门 FROM [Sheet2$] AS A Left Outer JOIN [Sheet1$] AS B ON A.姓名=B.姓名
--简写为
SELECT A.姓名,性别,部门 FROM [Sheet2$]A Left JOIN [Sheet1$]B ON A.姓名=B.姓名

join除了left join外还有right join,inner join等,之间的区别与sql语句都是一致的。注意VBA中的SQL是不支持outer join连接的

4.三表连接

如果需要连接多个表,可以按照上述两表连接的语法写多次即可。注意语句中的括号,在VBA SQL中不使用括号会导致错误

select A.姓名,B.性别,C.部门 from ([Sheet2$] as A left JOIN [Sheet1$] as B on A.姓名=B.姓名) left JOIN [Sheet3$] as C on A.姓名=C.姓名

5.数据透视表

TRANSFORM语句可以实现像透视表一样的显示结果,语法结构为:

TRANSFORM 汇总方式  SELECT 行标签 from 表名 group by 行字段 PIVOT 列标签

这一语句是非常常用的方法,要注意TRANSFORM后的汇总方式为一个聚合函数(一般为sum),同时后续的SELECT语句中不要加入a字段/b字段或者having语句,否则会导致语句错误无法运行
eg:
原始数据表如下

运行如下语句输出数据透视表:

TRANSFORM Sum(数量) Select 产品名称 from [Sheet1$] group by 产品名称 PIVOT 款号

可得到如下结果:

TRANSFORM语句话还可以加入一些自定义的设置:

TRANSFORM 汇总方式  SELECT 行标签 from 表名 group by 行字段 PIVOT 列标签 in [列标签值1,列标签值2,列标签值3.....]

使用in可以限制列标签的内容,同时可以规定列字段值的展示顺序

4.一些其他SQL语句的补充

条件判断/case语句的替代

在SQL中使用广泛的case关键字在VBA SQL中的实现方式为IIF,IIF的语法为:

IIf(Logical EXPression, Numeric Expression1, Numeric Expression2)

如果 Logical Expression 取值为 TRUE,则此函数返回 Numeric Expression1,否则,返回 Numeric Expression2。

例如:
当site列填NA时,将if_address设为N,否则设为Y

select name,iif([site]='NA','N','Y') as if_address form [student$]

同理,Logical Expression可以使用isnull,数字等值判断语句等

同时iif语句对符合条件的数据进行计算。例如如果是赠送的,实际的花费为0,否则为原价购买计算花费

select 客户,sum(iif(buying_type='赠送',price,0)) as cost  from  [order$]
从其他文件中引用数据

如果SQL中的数据涉及到不同的Excel表,可以直接从其他文件获取数据的SQL语句:

Select * From [盘符:\路径\工作簿名1.后辍名].[工作表名$] Union All Select * From [盘符:\路径\工作簿名2.后辍名].[工作表名$] Union All Select * From [盘符:\路径\工作簿名3.后辍名].[工作表名$]
数据没有列标题

如果工作表没有列标题,用F1,F2,F3,F4…这样代替

字段名解决特殊字符问题

如果列标题中有特殊字符如单引号、斜杠、百分号等。或者关键字:from、in、select、where等,可以用[ ]将字段包起来表示这是一个字段名,例如:

Select [%百分比]  FROM [Sheet1$]

在VBA中使用SQL的更多相关文章

  1. 在Excel VBA中写SQL,是一种什么体验

    每每提到Excel办公自动化,我们脑海里能想到的就是公式.数据透视表.宏.VBA,这也是我们大部分人数据分析的进阶之路.当我们对于常用VBA技巧已经相当熟练后,往往会有一种"我的VBA知识够 ...

  2. 在Excel VBA中使用SQL到底优势在哪儿

    小爬在之前的博文中多次提到,可以在VBA中写SQL来操作Excel文件,实现各类数据处理和分析需求.那么,你可能有这样的疑问:Excel原生的VBA,数据透视表,数据分析功能不够吗,为啥一定要用SQL ...

  3. Excel VBA中写SQL,这些问题的方法你一定要牢记

    小爬之前的文章 [Excel VBA中写SQL,这些问题你一定为此头痛过]中详细讲诉了一些常见的VBA 中使用SQL遇到的问题,这里再补充两个常见的问题场景及对应的解决方案,希望你们看了后能够思路开阔 ...

  4. 在EXCEL中使用SQL语句查询

    SQL语句在数据库使用中十分重要. 在EXCEL中可以不打开工作簿,就获取数据,对多工作簿操作很用,也很快. 对大量数据处理,比循环快很多,但是比词典方法还有点距离(可惜我还没有学会词典). 对数据库 ...

  5. 监视EntityFramework中的sql流转你需要知道的三种方式Log,SqlServerProfile, EFProfile

    大家在学习entityframework的时候,都知道那linq写的叫一个爽,再也不用区分不同RDMS的sql版本差异了,但是呢,高效率带来了差灵活性,我们 无法控制sql的生成策略,所以必须不要让自 ...

  6. 在Windows Server 2012 R2中搭建SQL Server 2012故障转移集群

    需要说明的是我们搭建的SQL Server故障转移集群(SQL Server Failover Cluster)是可用性集群,而不是负载均衡集群,其目的是为了保证服务的连续性和可用性,而不是为了提高服 ...

  7. 在Excel中使用SQL语句查询和筛选

    本文转自:http://blog.sina.com.cn/s/blog_5fc375650102e1g5.html 今天在微博上看到@数据分析精选 分享的一篇文章,是关于<在Excel中使用SQ ...

  8. EF中执行sql语句,以及事务

    EF to sql string sql = "select T_Task.BSID,T_Task.CloseDate,T_Task.CompleteDate,T_Task.CloseUse ...

  9. Oracle中PL/SQL的执行部分和各种流程控制

    Oracle中PL/SQL的执行部分和异常部分 一.PL/SQL的执行部分. 赋值语句. 赋值语句分两种,一种是定义一个变量,然后接收用户的IO赋值:另一种是通过SQL查询结果赋值. 用户赋值举例: ...

  10. VB类模块中属性的参数——VBA中Range对象的Value属性和Value2属性的一点区别

    在VB中,属性是可以有参数的,而VBA中属性使用参数非常常见.比如最常用的:Worksheet.Range("A1:A10")  VB的语法,使用参数的不一定是方法,也有可能是属性 ...

随机推荐

  1. C 图上的遍历算法

    图上的遍历算法 广度优先搜索 BFS 概念 广度优先搜索(Breadth-First Search)是一种图遍历算法,用于在图或树中按层次逐层访问节点.它从源节点(起始节点)开始,首先访问源节点的所有 ...

  2. 云备份技术解析:备份删除&合并原理

    本文分享自天翼云开发者社区<云备份技术解析:备份删除&合并原理>,作者:沈****军 在删除备份副本时,需要根据备份副本包含的数据块以及数据块的引用关系来进行空间的释放.当云硬盘的 ...

  3. 做Docx预览,一定要做这个神库!!

    Hey, 我是 沉浸式趣谈 本文首发于[沉浸式趣谈],我的个人博客 https://yaolifeng.com 也同步更新. 转载请在文章开头注明出处和版权信息. 如果本文对您有所帮助,请 点赞.评论 ...

  4. 你了解 Java 的类加载器吗?

    Java 类加载器(ClassLoader) Java 中的类加载器是用于加载 .class 文件到 JVM 中的组件,它的核心作用是将字节码(.class 文件)加载到内存,并且使它能够被 JVM ...

  5. SpringMVC框架第一天

    目录 SpringMVC的基本概念 三层架构和MVC 三层架构 MVC模型 MVC概述 SpringMVC是什么 SpringMVC在三层架构的位置 SpringMVC的优势 SpringMVC的入门 ...

  6. Java---switch...case中case可以匹配些什么

    switch-case语句 case 标签可以是 : •类型为 char.byte.short 或 int 的常量表达式. •枚举常量. •从 Java SE 7 开始,case 标签还可以是字符串字 ...

  7. 仿EXCEL插件,智表ZCELL产品V2.0 版本发布,优化全键盘操作,增加JSON格式导入导出功能

    详细请移步 智表(ZCELL)官网www.zcell.net 更新说明  这次更新主要应用户要求,主要一方面重构了底层,优化了键盘操作,支持全键盘录入,另一方面增加了JSON格式的导入导出,支持终端用 ...

  8. Python基础 - 控制结构

    控制结构: 顺序, 分支, 循环, 理解了, 其实编程就入门一半了. 条件表达式 条件表达式的值只要不是:0 . None. False. 空列表. 空元组. 空集合. 空字典. 空字符串. 空ran ...

  9. Java 枚举类的简单介绍

    综述   enum 的全称为 enumeration, 是Java1.5引入的新特性,通过关键字enum来定义枚举类.它是一种特殊类,和普通类一样可以使用构造器.定义成员变量和方法,也能实现一个或多个 ...

  10. Linux环境使用apt-get安装telnet、curl、ifconfig、vim、ping等工具【转】

      当在Linux服务器执行Telnet命令时,如果提示command not found: telnet,说明服务器上并未安装Telnet命令,需要安装此命令.下面介绍在linux服务器如何安装te ...