如何:使用表以外的对象创建查询
每次编写检索查询时,必须明确说明想要的列、想要的行以及查询处理器应在哪里查找原始数据。 一般情况下,原始数据由一个表或几个联接在一起的表组成。 但是原始数据也可以来自表以外的源。 事实上,它可以来自视图、查询、同义词或返回表的用户定义函数。
使用视图代替表
可以从视图选择行。 例如,假设数据库包含一个名为“ExpensiveBooks”的视图,在该视图中,每行描述一个价格超过 19.99 美元的书名。 视图定义可能像下面这样:
SELECT *
FROM titles
WHERE price > 19.99
可以选择较贵的心理学书籍,方法只不过是从 ExpensiveBooks 视图中选择心理学书籍。 得到的 SQL 可能像下面这样:
SELECT *
FROM ExpensiveBooks
WHERE type = 'psychology'
同样,视图可以参与 JOIN 操作。 例如,可以查找较贵的书的销售额,方法只不过是将 sales 表联接到 ExpensiveBooks 视图。 得到的 SQL 可能像下面这样:
SELECT *
FROM sales
INNER JOIN
ExpensiveBooks
ON sales.title_id
= ExpensiveBooks.title_id
有关将视图添加到查询的更多信息,请参见 如何:向查询添加表。
用查询代替表
可以从查询选择行。 例如,假设编写了一个查询,检索合著书(有一个以上作者的书)的书名和标识符。 所得到的 SQL 可能像下面这样:
SELECT
titles.title_id, title, type
FROM
titleauthor
INNER JOIN
titles
ON titleauthor.title_id
= titles.title_id
GROUP BY
titles.title_id, title, type
HAVING COUNT(*) > 1
然后可以编写另一个建立在该结果上的查询。 例如,可以编写一个查询检索合著的心理学书籍。 若要编写这个新查询,可以将现有查询用作这个新查询的数据源。 得到的 SQL 可能像下面这样:
SELECT
title
FROM
(
SELECT
titles.title_id,
title,
type
FROM
titleauthor
INNER JOIN
titles
ON titleauthor.title_id
= titles.title_id
GROUP BY
titles.title_id,
title,
type
HAVING COUNT(*) > 1
)
co_authored_books
WHERE type = 'psychology'
加粗的文本表示用作新查询的数据源的现有查询。 注意新查询使用了现有查询的别名(“co_authored_books”)。 有关别名的更多信息,请参见 如何:创建表别名 和 如何:创建列别名。
同样,查询可以参与 JOIN 操作。 例如,可以查找较贵的合著书籍的销售额,方法只不过是将 ExpensiveBooks 视图联接到检索合著书籍的查询。 得到的 SQL 可能像下面这样:
SELECT
ExpensiveBooks.title
FROM
ExpensiveBooks
INNER JOIN
(
SELECT
titles.title_id,
title,
type
FROM
titleauthor
INNER JOIN
titles
ON titleauthor.title_id
= titles.title_id
GROUP BY
titles.title_id,
title,
type
HAVING COUNT(*) > 1
)
有关将查询添加到查询的更多信息,请参见 如何:向查询添加表。
使用用户定义函数代替表
在 SQL Server 2000 或更高版本中,可以创建返回表的用户定义函数。 这类函数对执行复杂逻辑关系或过程逻辑关系很有用。
例如,假设 employee 表包含一个附加列 employee.manager_emp_id,且存在从 manager_emp_id 到 employee.emp_id 的外键。 在 employee 表的每一行内,manager_emp_id 列指示雇员的老板。 更确切地说,它显示职员的老板的 emp_id。 可以创建用户定义函数以返回这样的表:在某个特定高级经理的组织层次结构内工作的每个职员在表中各占一行。 可以调用函数 fn_GetWholeTeam,并设计它获得一个输入变量(待检索部门经理的 emp_id)。
可以编写将 fn_GetWholeTeam 函数用作数据源的查询。 得到的 SQL 可能像下面这样:
SELECT *
FROM
fn_GetWholeTeam ('VPA30890F')
“VPA30890F”是待检索部门经理的 emp_id。 有关将用户定义函数添加到查询的更多信息,请参见 如何:在查询中包含用户定义的函数 和 如何:向查询添加表。 有关用户定义函数的完整说明,请参见 SQL Server 文档。