4.3.4 查询语法基础(1)
“查询”这个术语有点误导作用。一般常把查询看做一个问题,人们常常把“查询”与T-SQL中的select语句联系起来。但无论T-SQL包含select、update、delete还是insert语句,都是一个查询。查询更像一个句子,而且必须是一个完整的语句,至少要有名词和动词。sql语义规则定义了一个简单的结构。下面的子句说明要做什么:select、insertupdate或者delete,这些都是动词。此外,还需要定义要返回的列或值,通常需指定要操作的表或者其他数据库对象,这是宾语或者名词。根据操作的类型,句子中可以有像FROM和Into这样的连接词。
要从Product表中检索所有行和所有列的值,可执行下列查询:
select * from Production.Product
下面这条语句用于实现把所有产品的价格提升10%;
update Production.Product set StandardCost=StandardCost*1.1
T-SQL语言对语句的格式是非常宽容的。SQL Server查询处理引擎不关心命令是大写还是小写形式,也不关心空格、制表符、回车换行符,只要不与命令或者值冲突即可。因此,可以按可读性原则随意制定脚本的格式。比如,下列查询返回某个日期范围内的产品销售消息,它以产品类别和子类别排序。这个查询可以书写成:
select Production.ProductCategory.Name as Category,
Production.ProductSubCategory.Name as SubCategory,
Production.Product.Name as ProductName,
Sales.SalesOrderHeader.OrderDate,
Sales.SalesOrderDetail.OrderQty,
Sales.SalesOrderDetail.UnitPrce
from Sales.SalesOrderHeader inner
join Sales.SalesOrderDetail on
Sales.SalesOrderHeader.SalesOrderID=Sales.SalesOrderDetail.SalesOrderID
inner join Production.Product on
Sales.SalesOrderDetial.ProductID=Product.ProductID
inner join production.ProductSubCategory on Production.Product.ProductSubCategoryID=Production.ProductSubCategory.ProductSubCategoryID
inner join Production.ProductCategory on Producttion.ProductSubCategory.ProductCategoryID=Production.ProductCategory.ProductCategoryID
where Sales.SalesOrderHeader.OrderDate
between '1/1/2003' and '12/31/2003'
order by Production.ProductCategory.Name,
Production.ProductSubCategory.Name,
Production.Product.Name
- SELECT Production.ProductCategory.Name
AS Category, Production. - ProductSubCategory.Name AS SubCategory ,
Production.Product.Name AS - ProductName ,Sales.SalesOrderHeader.
OrderDate,Sales.SalesOrderDetail. - OrderQty,Sales.SalesOrderDetail.UnitPrice
- FROM Sales.SalesOrderHeader INNER
JOIN Sales.SalesOrderDetail ON - Sales.SalesOrderHeader.SalesOrderID =
Sales.SalesOrderDetail.SalesOrderID - INNER JOIN Production.Product ON Sales.
SalesOrderDetail.ProductID = Product. - ProductID INNER JOIN Production.
ProductSubCategory ON Production. - Product.ProductSubCategoryID =
Production.ProductSubCategory. - ProductSubCategoryID INNER JOIN
Production.ProductCategory - ON Production.ProductSubCategory.
ProductCategoryID = Production. - ProductCategory.ProductCategoryID
- WHERE Sales.SalesOrderHeader.OrderDate
BETWEEN '1/1/2003' AND '12/31/2003' - ORDER BY Production.ProductCategory.Name,
Production.ProductSubCategory. - Name,Production.Product.Name
也可以写成这样:
select Production.ProductCategory.Name as Category,
Production.ProductSubCategory.Name as SubCategory,
Production.Product.Name as ProductName,
Sales.SalesOrderHeader.OrderDate,
Sales.SalesOrderDetail.OrderQty,
Sales.SalesOrderDetail.UitPrice
from Sales.SalesOrderHeader
inner join Sales.SalesOrderDetail on Sales.SalesOrderHeader.SalesOrderId=Sales.SalesOrderDetail.SalesOrderID
inner join Production.Product on Sales.SalesOrderDetail.ProductID=Product.ProductID
inner join Production.ProductSubCategory on Production.Product.ProductSubCategoryID=Production.ProductSubCategory.ProductSubCategoryID
inner join Production.ProductCategory on Production.ProductSubCategory.ProductCategoryID=Production.ProductCategory.ProductCategoryID
where Sales.SalesOrderHeader.OrderDate
between '1/1/2003' and '12/31/2003'
order by Production.ProductCategory.Name, Production.ProductSubCategory.Name,Production.Product.Name
- SELECT Production.ProductCategory.Name AS Category
- ,Production.ProductSubCategory.Name AS SubCategory
- ,Production.Product.Name AS ProductName
- ,Sales.SalesOrderHeader.OrderDate
- ,Sales.SalesOrderDetail.OrderQty
- ,Sales.SalesOrderDetail.UnitPrice
- FROM Sales.SalesOrderHeader
- INNER JOIN Sales.SalesOrderDetail
- ON Sales.SalesOrderHeader.SalesOrderID =
- Sales.SalesOrderDetail.SalesOrderID
- INNER JOIN Production.Product
- ON Sales.SalesOrderDetail.ProductID = Product.ProductID
- INNER JOIN Production.ProductSubCategory
- ON Production.Product.ProductSubCategoryID =
- Production.ProductSubCategory.ProductSubCategoryID
- INNER JOIN Production.ProductCategory
- ON Production.ProductSubCategory.ProductCategoryID =
- Production.ProductCategory.ProductCategoryID
- WHERE Sales.SalesOrderHeader.OrderDate BETWEEN
'1/1/2003' AND '12/31/2003' - ORDER BY Production.ProductCategory.Name
- ,Production.ProductSubCategory.Name
- ,Production.Product.Name
显然,有一种查询更易读,更容易看出这个查询的具体用途。代码格式的易读性完全有T-SQL程序员确保。第一个例子比较混乱,但第二个例子已经经过了格式化,所以容易理解。但第二个代码仍然不是尽善尽美的。我们可以使用表别名来整理代码,删除多余的模式和表引用。为此,只需在From或Join子句中第一次引用表后创建别名即可。别名类似于昵称,把昵称放在对象给定名称的后面,就给对象指定了新名称,如下面的例子所示:
select PC.Name as Category,
PSC.Name as SubCategory,
P.Name as ProductName,
SOH.OrderDate,
SOD.OrderQty,
SOD.UnitPrice
from Sales.SalesOrderHeader as SOH
inner join Sales.SalesOrderDetail as SOD on SOH.Sales.OrderID=SOD.SalesOrderID
inner join Production.Product as P on SOD.ProductID=P.ProductID
inner join Production.ProductSubCategory as PSC on P.ProductSubCategoryID=PSC.ProductSubCategoryID
inner join Production.ProductCategory as PC on PSC.ProductCategoryID=PC.ProductCategoryID
where SOH.OrderDate between '1/1/2003' and '12/31/2003'
order by PC.Name,PSC.Name,P.Name
- SELECT PC.Name AS Category
- ,PSC.Name AS SubCategory
- ,P.Name AS ProductName
- ,SOH.OrderDate
- ,SOD.OrderQty
- ,SOD.UnitPrice
- FROM Sales.SalesOrderHeader AS SOH
- INNER JOIN Sales.SalesOrderDetail AS SOD
- ON SOH.SalesOrderID = SOD.SalesOrderID
- INNER JOIN Production.Product AS P
- ON SOD.ProductID = P.ProductID
- INNER JOIN Production.ProductSubCategory AS PSC
- ON P.ProductSubCategoryID = PSC.ProductSubCategoryID
- INNER JOIN Production.ProductCategory AS PC
- ON PSC.ProductCategoryID = PC.ProductCategoryID
- WHERE SOH.OrderDate BETWEEN '1/1/2003' AND '12/31/2003'
- ORDER BY PC.Name
- ,PSC.Name
- ,P.Name