创建一个视图,整合 SQL 中以前的视图

Create a view integrating previous views in SQL

我使用 AdventureWorks2014 中的数据在我的新数据库中创建了三个视图。三个视图编译保存都很好,没有问题。但是,当我尝试制作一个包含所有三个视图的完整视图时,似乎没有任何效果。

观看次数 creationcreation2creation3

ALTER VIEW [creation] AS
SELECT sd.ProductID, YEAR(sh.OrderDate) AS 'Year',
 MONTH(sh.OrderDate)AS 'Month', DAY(sh.OrderDate) AS 'Day',
sd.UnitPrice AS 'Value', sd.OrderQty AS 'Quantity', NULL AS 'col7',
NULL AS 'col8'
FROM AW2014.Sales.SalesOrderHeader AS sh
INNER JOIN AW2014.Sales.SalesOrderDetail AS sd
ON sd.SalesOrderID = sh.SalesOrderID
INNER JOIN AW2014.Sales.Customer AS c
ON c.CustomerID = sh.CustomerID
INNER JOIN AW2014.Person.Person AS p
ON p.BusinessEntityID = c.PersonID
WHERE p.PersonType LIKE 'IN'

ALTER VIEW [creation2]AS
SELECT p.FirstName, p.MiddleName, p.LastName,
CONCAT(a.AddressLine1, ' ',a.AddressLine2,', ',a.City) AS 'Address',
cr.Name, NULL AS 'col6', NULL AS 'col7', NULL AS 'col8'
FROM AW2014.Person.Person AS p
INNER JOIN AW2014.Person.BusinessEntityAddress AS bea
ON p.BusinessEntityID= bea.BusinessEntityID
INNER JOIN AW2014.Person.Address AS a
ON bea.AddressID = a.AddressID
INNER JOIN AW2014.Person.StateProvince AS sp
ON a.StateProvinceID = sp.StateProvinceID
INNER JOIN AW2014.Person.CountryRegion AS cr
ON sp.CountryRegionCode = cr.CountryRegionCode
WHERE p.PersonType LIKE 'IN'

ALTER VIEW [creation3] AS
SELECT DISTINCT p1.ProductID, p1.Name AS 'Product', pc.Name AS 'Category', 
sc.Name AS 'Subcategory',
p1.StandardCost, p1.Color, p1.Weight, CONCAT(p1.SizeUnitMeasureCode,', ',p1.WeightUnitMeasureCode) AS 'Units'
FROM AW2014.Production.Product AS p1
INNER JOIN AW2014.Production.ProductSubcategory AS sc
ON p1.ProductSubcategoryID = sc.ProductSubcategoryID
INNER JOIN AW2014.Production.ProductCategory AS pc
ON pc.ProductCategoryID = sc.ProductCategoryID
INNER JOIN AW2014.Sales.SalesOrderDetail AS sd
ON p1.ProductID = sd.ProductID
INNER JOIN AW2014.Sales.SalesOrderHeader AS sh
ON sd.SalesOrderID = sh.SalesOrderID
INNER JOIN AW2014.Sales.Customer AS c
ON sh.CustomerID = c.CustomerID
INNER JOIN AW2014.Person.Person AS p
ON c.PersonID = p.BusinessEntityID
WHERE p.PersonType LIKE 'IN'

我让每个视图都有相同数量的列,正如我在堆栈上读到的那样,如果我想使用 union 语句,我应该这样做。我是这样做的:

CREATE VIEW [a] AS
SELECT * FROM [creation2]
UNION ALL
SELECT * FROM [creation]

我收到一条消息,提示我的命令已成功完成。然而,当我尝试 SELECT * FROM [a] 时,它无休止地执行而没有结果。在下拉菜单中选中 dbo.a 后,它仅有的列是第一个视图中的列(在本例中为 creation2)。就好像它忽略了(或不能执行?) unionunion all 语句。

我也尝试使用 JOIN,为每个视图添加一个 p.PersonType 列,并将它们连接到这些视图上。只要我只选择它们,它就可以正常工作,但是当我尝试将它们放入新视图时,我收到一个错误,即视图应该有不同的列。如果我想加入他们,我不能让它与众不同,可以吗? 无论哪种方式,我的问题都是——考虑到上述所有这些选项都让我失望,我如何才能将我的所有三个观点转化为一个新观点?也许你有一些提示,也许我在我的代码中犯了一些愚蠢的错误?我以前但几年前使用过 SQL,我也喜欢任何改进技巧。

我正在使用 Microsoft SQLServer Management Studio 2017 顺便说一句。谢谢!

您应该联接由 3 个视图公开的列,而不是 UNION ALL,因为连接不相关视图的结果是不合适的。

您不能将 SELECT * 用于视图,因为这会导致重复的列名。无论如何,最好指定一个明确的列列表,并在需要时指定一个列别名以区分列 returned 和不同的 tables。我还建议有意义的视图名称,如上面的示例,因为这将使正确查询的关系更容易理解。

为了在带有连接的查询中轻松使用视图,每个视图通常应该公开一个或多个唯一标识行的列(如 table 中的主键)。 PersonType 在任何视图中都不是唯一的,因此会导致多对多连接和 return 很多行。在这种情况下,该连接没有逻辑意义。联接通常应该是一对一或一对多关系。