上一篇的 sql 语句蛮简单的,接下来,来看一个相对复杂的的场景。假设我们要编写一个查询,计算期间物料进出存的查询。需要用到 5 个表,将创建表的 sql 语句贴在下面,示例数据也已经上传到 github。
物料主数据表 (material_numbers):
create table material_numbers (
[MaterialNo] varchar(20) primary key,
[Description_e] varchar(100) null,
[Description_c] varchar(100) null
仓位 (storage_locations)
create table storage_locations(
[StorageLocation] varchar(10) PRIMARY KEY,
[LocationType] varchar(10) NULL,
[Description] varchar(50) NULL
movement_types:
CREATE TABLE movement_types(
[MovementTypeID] varchar(10) PRIMARY KEY,
[Description] varchar(50) NULL,
[InOutSign] varchar(1) NULL
stock_movement_headers:
CREATE TABLE stock_movement_headers(
[DocNo] varchar(10) PRIMARY KEY,
[MovementType] varchar(10) NULL,
[RefDocNo] varchar(10) NULL,
[VendorID] varchar(10) NULL,
[CustomerID] varchar(10) NULL,
[DocDate] datetime NULL,
[PeriodID] varchar(10) NULL,
[GCInvoiceNo] varchar(15) NULL,
[LongText] text NULL,
[PostedBy] varchar(10) NULL,
[PostedDate] datetime NULL,
[Remarks] varchar(255) NULL
stock_movement_details:
CREATE TABLE stock_movement_details(
[DocNo] varchar(10),
[MaterialNo] varchar(20),
[StorageLocation] varchar(10) NULL,
[Qty] float NULL,
[Remarks] varchar(255) NULL,
PRIMARY KEY(DocNo, MaterialNo)
在 MS Access 中表主要字段及表之间的关系:

查询条件是计算出 2008 年 4 月份物料的进出存,筛选条件:
- MaterialNo: Like "B180*'
- StorageLocation: 1001
最终的数据显示格式如下:
首先构建 material_numbers 和 storage_locations 的组合 (笛卡尔乘积)。考虑到有些物料没有交易数据,这种组合能得到交易项全部为 0 的数据。在查询设计界面中,加入 material_numbers 和 storage_locations 两个表,双击 MaterialNo 和 StorageLocation 字段,将其加入到查询的字段。两个表为独立的状态,这样查询的结果就是一种笛卡尔乘积。在【条件】中,MaterialNo 输入 “B180*”, StorageLocation 输入 “1001”:

选中 material_numbers 表,将右边【属性表】表的别名改为 M,同样的方法将 storage_locations 表的别名改为 L。设置别名的目的是让 SQL 语句变得清晰。如果【属性表】没有出现,选中表,右键菜单有【属性】项,点击调出。完成后的界面应该如下所示:

进入 SQL 视图,此时 SQL 语句如下。因为 Access 不支持代码格式化和高亮,代码借助 Visual Studio Code 进行格式化。
SELECT
M.MaterialNo,
L.StorageLocation
material_numbers AS M,
storage_locations AS L
WHERE
((M.MaterialNo) Like "B180*")
AND ((L.StorageLocation) = "1001")
新建一个查询,将查询命名为 txns。查询基于三个表:
- stock_movement_headers: 交易表头
- stock_movement_details : 交易行项目
- movement_types : 移动类型,表示出入库的类型
因为没有维护表之间的关系,需要在查询中维护 stock_movement_headers 表和 movement_types 表之间的关系(左连接):
双击或拖放的方式选中需要的字段到查询中:

为了方便后面的根据年月筛选,基于 DocDate 新增两个计算字段: TxYear 和 TxMonth,分别表示交易的年和月。在表达式生成器中维护:


增加一个计算列 ActualQty, 正数表示入库,负数表示出库:
ActualQty: IIf([InOutSign]="+",Nz([Qty]),-1 * Nz([Qty]))
为了 SQL 语句更加清晰,设置三个表的别名:
H: stock_movement_headers
D: stock_movement_details
MVT: movement_types
然后对 materialNo 字段和 storageLocation 字段设置上一步相同的条件。设置完成后,查询设计视图的界面如下:
进入 SQL 视图,得到本步骤的 SQL 语句:
SELECT
H.DocDate,
D.MaterialNo,
D.StorageLocation,
H.MovementType,
D.Qty,
MVT.InOutSign,
Year([DocDate]) AS TxYear,
Month([DocDate]) AS TxMonth,
IIf([InOutSign] = "+", Nz([Qty]), -1 * Nz([Qty])) AS ActualQty
stock_movement_headers AS H
LEFT JOIN movement_types AS MVT ON H.MovementType = MVT.MovementTypeID
INNER JOIN stock_movement_details AS D ON H.DocNo = D.DocNo
WHERE
((D.MaterialNo) Like "B180*")
AND ((D.StorageLocation) = "1001")
运行一下查询,此时的界面如下:
接下来基于查询 txns 创建一个查询,使用行转列的方法增加三个计算列:
- BeginQty: 期初余额
- StockIn: 期间入库数量
- StockOut: 期间出库数量
将查询命名为 txn_summary,首先选取相关的列:

添加条件列,在表达式生成器界面中设置 BeginQty
的公式如下:
BeginQty: IIf([TxYear]<2008 Or ([TxYear]=2008 And [TxMonth]<4),[ActualQty],0)
同样的方法,添加计算列,得到物料入库数量和出库数量:
StockIn: IIf([TxYear]=2008 And [TxMonth]=4 And [InOutSign]="+",[ActualQty],0)
StockOut: IIf([TxYear]=2008 And [TxMonth]=4 And [InOutSign]="-",[ActualQty],0)
删除查询中不相关的字段(TxYear, TxMonth, InoutSign, ActualQty
),然后点击功能区上的汇总:

将需要计算的字段改为合计:

完成本步骤,得到的 SQL 语句为:
SELECT
txns.MaterialNo,
txns.
StorageLocation,
Sum(
IIf(
[TxYear] < 2008
Or (
[TxYear] = 2008
And [TxMonth] < 4
[ActualQty],
) AS BeginQty,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "+",
[ActualQty],
) AS StockIn,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "-",
[ActualQty],
) AS StockOut
GROUP BY
txns.MaterialNo,
txns.StorageLocation;
因为本步骤基于查询 txns,所以可以将查询稍加修改,并且插入上一步骤 txns 查询的代码。From 子句原来是这样的:

将其修改为:

括号中插入上一步 txns SQL 语句的码, 将其作为子查询:
SELECT
txns.MaterialNo,
txns.StorageLocation,
Sum(
IIf(
[TxYear] < 2008
Or (
[TxYear] = 2008
And [TxMonth] < 4
[ActualQty],
) AS BeginQty,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "+",
[ActualQty],
) AS StockIn,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "-",
[ActualQty],
) AS StockOut
SELECT
H.DocDate,
D.MaterialNo,
D.StorageLocation,
H.MovementType,
D.Qty,
MVT.InOutSign,
Year([DocDate]) AS TxYear,
Month([DocDate]) AS TxMonth,
IIf([InOutSign] = "+", Nz([Qty]), -1 * Nz([Qty])) AS ActualQty
stock_movement_headers AS H
LEFT JOIN movement_types AS MVT ON H.MovementType = MVT.MovementTypeID
INNER JOIN stock_movement_details AS D ON H.DocNo = D.DocNo
WHERE
((D.MaterialNo) Like "B180*")
AND ((D.StorageLocation) = "1001")
) AS txns
GROUP BY
txns.MaterialNo,
txns.StorageLocation;
联合查询 material (别名 MT) 和 txn_summary (别名 TX),创建一个新的查询:

此时的 SQL 语句为:
SELECT
MT.MaterialNo,
MT.StorageLocation,
TX.BeginQty,
TX.StockIn,
TX.StockOut,
[BeginQty] + [StockIn] + [StockOut] AS EndQty
materials AS MT
LEFT JOIN txn_summary AS TX ON (MT.StorageLocation = TX.StorageLocation)
AND (MT.MaterialNo = TX.MaterialNo);
将 FROM 子句后 materials
和 txn_summary
替换为子查询,得到最后完整的 SQL 语句:
SELECT
MT.MaterialNo,
MT.StorageLocation,
TX.BeginQty,
TX.StockIn,
TX.StockOut,
[BeginQty] + [StockIn] + [StockOut] AS EndQty
SELECT
M.MaterialNo,
L.StorageLocation
material_numbers AS M,
storage_locations AS L
WHERE
((M.MaterialNo) Like "B180*")
AND ((L.StorageLocation) = "1001")
) AS MT
LEFT JOIN (
SELECT
txns.MaterialNo,
txns.StorageLocation,
Sum(
IIf(
[TxYear] < 2008
Or (
[TxYear] = 2008
And [TxMonth] < 4
[ActualQty],
) AS BeginQty,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "+",
[ActualQty],
) AS StockIn,
Sum(
IIf(
[TxYear] = 2008
And [TxMonth] = 4
And [InOutSign] = "-",
[ActualQty],
) AS StockOut
SELECT
H.DocDate,
D.MaterialNo,
D.StorageLocation,
H.MovementType,
D.Qty,
MVT.InOutSign,
Year([DocDate]) AS TxYear,
Month([DocDate]) AS TxMonth,
IIf([InOutSign] = "+", Nz([Qty]), -1 * Nz([Qty])) AS ActualQty
stock_movement_headers AS H
LEFT JOIN movement_types AS MVT ON H.MovementType = MVT.MovementTypeID
INNER JOIN stock_movement_details AS D ON H.DocNo = D.DocNo
WHERE
((D.MaterialNo) Like "B180*")
AND ((D.StorageLocation) = "1001")
) AS txns
GROUP BY
txns.MaterialNo,
txns.StorageLocation
) AS TX ON (MT.StorageLocation = TX.StorageLocation)
AND (MT.MaterialNo = TX.MaterialNo);
github: stocks.accdb
《SQL Server 2008宝典》全面介绍了SQL Server 2008各方面的知识,全书由6部分组成:第1部分为数据库的基础篇,介绍了数据库的类型、概念、对象、SQL语言等;第2部分为SQLServer 2008的准备篇,介绍了SQL Server 2008的功能、特性、各版本的比较、安装方法、SQL Server 2008的服务、客户端的工具等;第3部分为SQL Server 2008的基本操作篇,介绍如何管理与配置SQL Server 2008服务器、如何创建数据库和数据表、如何对数据库里的数据进行操作;第4部分为数据库管理篇,介绍如何使用T-SQL程序对数据进行复杂的运算,以及如何使用视图、存储过程、触发器、索引、用户定义数据类型、用户定义函数、全文索引、游标、事务和锁、统计信息和同义词等方面的知识;第5部分为SQL Server高级技术,介绍如何进行数据库备份与恢复、如何规划数据库、如何保证数据库的安全、复制与发布、自动化管理、如何使用性能工具优化数据库、数据的导入导出、SQL Server邮件的使用、Analysis Services、Reporting Services、SQL Server与XML的应用,以及如何使用客户端和应用程序访问SQL Server;第6部分为SQL Server 2008改进篇,介绍了SQL Server 2008相对于之前版本进行了哪些方面的重大改进和优化,进一步帮助读者了解SQL Server 2008更多的独有特性。
《SQL Server 2008宝典》适合SQL Server 2008的初学者学习,也适合子数据库的管理人员和开发人员阅读和参考。
《SQL Server 2008宝典》:实例丰富,内容充实。书中针对每一个知识点列举了大量实例来说明该功能如何实现,全书共有超过500个精彩实例。
讲解通俗,步骤详细。通过通俗易懂的语言讲解SQL Server 2008的各个强大功能,并配以插图讲解和详细的步骤说明,帮助读者快速掌握实用技能。
由浅入深,难易穿插。《SQL Server 2008宝典》面向入门级和提高级两类读者,每个知识点都采用由浅入深的讲解方式,并穿插介绍重点和难点。
提供源码,方便学习。书中涉及到的T—SQL程序在网站上提供下载,打开相应SQL文件即可直接执行其中的代码。
SQL Server 2008是一个能用于大型联机事务处理、数据仓库和电子商务等方面应用的数据库平台,也是一个能用于数据集成、数据分析和报表解决方案的商业智能平台,为用户提供了强大、集成、便于使用的工具,使系统管理员与普通用户能更方便、更快捷地管理数据库或设计、开发应用程序。
封面 -33
封底 803
扉页 -32
版权 -31
前言 -30
目录 -26
第1部分 基础篇 1
第1章 认识数据库 2
1.1 数据库的类型 2
1.1.1 结构型数据库 2
1.1.2 网络型数据库 2
1.1.3 关系型数据库 2
1.1.4 面向对象型数据库 3
1.2 数据库的基本概念 3
1.2.1 数据 3
1.2.2 数据库 3
1.2.3 数据库管理系统 3
1.2.4 数据库系统 3
1.3 常见的数据库对象 3
1.3.1 表与记录 4
1.3.2 主键与外键 4
1.3.3 索引 4
1.3.4 约束 5
1.3.5 视图 5
1.3.6 关系图 5
1.3.7 默认值 5
1.3.8 规则 5
1.3.9 存储过程 6
1.3.10 触发器 6
1.3.11 用户和角色 6
1.4 数据库管理系统的基本功能 6
1.4.1 定义数据 6
1.4.2 处理数据 6
1.4.3 保证数据安全 6
1.4.4 备份和恢复数据 6
1.5 SQL语言简介 6
1.5.1 SQL语言的历史 7
1.5.2 SQL语言的优点 7
1.5.3 SQL语言分
《SQL Server 2008宝典》全面介绍了SQL Server 2008各方面的知识,全书由6部分组成:第1部分为数据库的基础篇,介绍了数据库的类型、概念、对象、SQL语言等;第2部分为SQLServer 2008的准备篇,介绍了SQL Server 2008的功能、特性、各版本的比较、安装方法、SQL Server 2008的服务、客户端的工具等;第3部分为SQL Server 2008的基本操作篇,介绍如何管理与配置SQL Server 2008服务器、如何创建数据库和数据表、如何对数据库里的数据进行操作;第4部分为数据库管理篇,介绍如何使用T-SQL程序对数据进行复杂的运算,以及如何使用视图、存储过程、触发器、索引、用户定义数据类型、用户定义函数、全文索引、游标、事务和锁、统计信息和同义词等方面的知识;第5部分为SQL Server高级技术,介绍如何进行数据库备份与恢复、如何规划数据库、如何保证数据库的安全、复制与发布、自动化管理、如何使用性能工具优化数据库、数据的导入导出、SQL Server邮件的使用、Analysis Services、Reporting Services、SQL Server与XML的应用,以及如何使用客户端和应用程序访问SQL Server;第6部分为SQL Server 2008改进篇,介绍了SQL Server 2008相对于之前版本进行了哪些方面的重大改进和优化,进一步帮助读者了解SQL Server 2008更多的独有特性。
《SQL Server 2008宝典》适合SQL Server 2008的初学者学习,也适合子数据库的管理人员和开发人员阅读和参考。
《SQL Server 2008宝典》:实例丰富,内容充实。书中针对每一个知识点列举了大量实例来说明该功能如何实现,全书共有超过500个精彩实例。
讲解通俗,步骤详细。通过通俗易懂的语言讲解SQL Server 2008的各个强大功能,并配以插图讲解和详细的步骤说明,帮助读者快速掌握实用技能。
由浅入深,难易穿插。《SQL Server 2008宝典》面向入门级和提高级两类读者,每个知识点都采用由浅入深的讲解方式,并穿插介绍重点和难点。
提供源码,方便学习。书中涉及到的T—SQL程序在网站上提供下载,打开相应SQL文件即可直接执行其中的代码。
SQL Server 2008是一个能用于大型联机事务处理、数据仓库和电子商务等方面应用的数据库平台,也是一个能用于数据集成、数据分析和报表解决方案的商业智能平台,为用户提供了强大、集成、便于使用的工具,使系统管理员与普通用户能更方便、更快捷地管理数据库或设计、开发应用程序。
封面 -33
封底 803
扉页 -32
版权 -31
前言 -30
目录 -26
第1部分 基础篇 1
第1章 认识数据库 2
1.1 数据库的类型 2
1.1.1 结构型数据库 2
1.1.2 网络型数据库 2
1.1.3 关系型数据库 2
1.1.4 面向对象型数据库 3
1.2 数据库的基本概念 3
1.2.1 数据 3
1.2.2 数据库 3
1.2.3 数据库管理系统 3
1.2.4 数据库系统 3
1.3 常见的数据库对象 3
1.3.1 表与记录 4
1.3.2 主键与外键 4
1.3.3 索引 4
1.3.4 约束 5
1.3.5 视图 5
1.3.6 关系图 5
1.3.7 默认值 5
1.3.8 规则 5
1.3.9 存储过程 6
1.3.10 触发器 6
1.3.11 用户和角色 6
1.4 数据库管理系统的基本功能 6
1.4.1 定义数据 6
1.4.2 处理数据 6
1.4.3 保证数据安全 6
1.4.4 备份和恢复数据 6
1.5 SQL语言简介 6
1.5.1 SQL语言的历史 7
1.5.2 SQL语言的优点 7
1.5.3 SQL语言分
在对access数据库进行数据查询的时候要注意,where后面的条件要加单引号:select * from 故障记录 where 故障现象代码='F001'多条件查询实现的代码如下:string sql = "select * from 故障记录 where";
if(textBox_machine.Text!="")
sql += " 机器编号=" + ...
Office 家族中,平时使用 MS Acess 的人非常少,如果从工作效率的角度来说,掌握了 Access,很多时候岂止是事半功倍啊!下面就介绍一种基于 Access 查询轻松构造 SQL 语句的方法。因为本文面向把 MS Office 作为办公工具的用户,熟练编写 SQL 语句的请忽略。
假设我们有如下的员工工时记录表:
目标是按固定月份 (1~12 月)的格式统计员工的工时,格式如下...
2011-05-28 20:39:59转载自http://www.cnblogs.com/everyday/archive/2009/09/24/1573612.htmlACCESS里面的iff的用法就相当于SQL里面的case when end.
具体的用法如下:SQL server 支持的查询语句命令case when:结构如下:casewhen 条件1 then 结果1when 条件2 then 结果2……end在access中,不支持case when 结构,使用 iif 代替:结构如
很多初学Access的朋友都说sql 语句不会写,把它归纳为难点,不想写。其实不然,大家都知道sql 在查询中的作用非常非常的大,是不得放弃的模块。其实语法也是很简单,常用的就以下几种:
基本查询
SELECT column1,columns2,... FROM table_name
说明:把table_name 的特定栏位资料全部列出来
SELECT *
FROM table_name
<br>4、 提供了强大的QueryFilter类构造查询条件,使得实现数据查询不再需要编写复杂的SQL语句;
<br>5、 提供类似IBatisNet的Sql模板功能,为复杂的查询统计提供较直观的开发模式;
<br>6、 提供代码生成...
<br>4、 提供了强大的QueryFilter类构造查询条件,使得实现数据查询不再需要编写复杂的SQL语句;
<br>5、 提供类似IBatisNet的Sql模板功能,为复杂的查询统计提供较直观的开发模式;
<br>6、 提供代码生成...
很多时候为了程序的可扩展性和准确性等我们会在数据库中把对应bool类型或string类型的字段设置为int型。但是在程序中显示的时候我们希望能显示用户友好的内容,这个时候我们就需要把查找到的结果转换成用户友好的结果。要达到这个目的有几种方法可行,可以在查询的时候直接按照要求判断输出,也可以在查询到结果后在程序中通过相应方法更改结果后显示。本文讨论第一种方法。
使用SQL Server数据库和使用
简单介绍一些谓词的使用和意义。 在代码中我们经常会使用一些条件语句来进行数据的查询和筛选,今天就初步讲一下常用的谓词查询。 谓词BETWEEN……AND 从字面意义上来讲就是在两者之间,所以使用BETWEEN……AND字句可以查找属性值在指定连续的范围内的元组。与之相对的是NOT BETWEEN…AND ,表示不在指定范围内的元组。 示例: select * fr...