创建在SQL中集成先前视图的视图

时间:2017-10-29 14:47:38

标签: sql sql-server views

我使用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 btw。谢谢!

1 个答案:

答案 0 :(得分:0)

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

如果导致重复的列名称,则无法将SELECT *用于视图。无论如何,最佳方法是指定显式列列表,并在需要时指定列别名以区分从不同表返回的列。我还建议像上面的示例那样有意义的视图名称,这样可以更容易理解正确查询的关系。

要在具有连接的查询中轻松使用视图,每个视图通常应公开一个或多个唯一标识行的列(如表中的主键)。 PersonType在任何视图中都不是唯一的,因此会导致多对多连接并返回大量行。在这种情况下,这种联接在逻辑上是不合理的。联合通常应该是一对一或一对多的关系。