【问题标题】:Create a view integrating previous views in SQL在 SQL 中创建一个集成以前视图的视图
【发布时间】:2023-04-01 10:55:02
【问题描述】:

我使用 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 顺便说一句。谢谢!

【问题讨论】:

  • 你的代码没问题。这些观点正在发挥作用。优化不是您所期望的。返回的行往往来自第一个视图。 . .你可能需要滚动(很多)才能看到更多。
  • 你不能用不同的列和类型来联合事物。奇怪的是,如果它们不一样,甚至创建了视图。也许您可以解释您要实现的目标,而不是想知道为什么这不起作用,特别是如果您正在尝试完全不同的联合和联接。
  • @GordonLinoff 是的,但我无处可滚动?新视图 [a] 甚至没有向我显示任何内容。当我选择它时它不会执行。在我的数据库的下拉菜单中,我可以清楚地看到所有列(只有 8 个),它们只是来自 [creation2] :(
  • @SamiKuhmonen 是的,当然!我想要实现的是创建一个新视图,我们称之为 [a],它将包含来自所有 3 个视图 [creation]、[creation2] 和 [creation3] 的所有列。当我一直在网上寻找解决方案时,每个人都说要使用联合,只要我试图包含的每个视图中的列数相同,它就应该可以工作。那么,有什么方法可以将每个视图中的所有列转换为相同的类型,以便我可以将它们合并为 [a]?不丢失数据?我希望这能澄清我的意图......
  • UNION 适用于合并来自不同来源的具有相同列的数据的情况。例如来自三个来源的名字和姓氏。在这里你没有那个,数据是不同的。所以你很可能想要他们之间的 JOIN 。您只需定义如何将它们连接在一起,即表之间的哪些列彼此相等。假设那将是表格 Person,因为它在每个表格中。

标签: sql sql-server views


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2013-04-03
    • 1970-01-01
    相关资源
    最近更新 更多