使用UNION ALL在SQL Server中创建视图

时间:2012-07-07 09:55:38

标签: sql-server

请考虑以下示例:

CREATE VIEW VW_YearlySales
AS

SELECT 2011 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2011
UNION ALL
SELECT 2012 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2012
UNION ALL
SELECT 2013 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2013

GO

InvoiceTable2013实际上并不存在,我现在不想创建它,它会在记录2013年的第一张发票时自动创建。

在执行UNION ALL之前,有没有人能帮助我如何指定一个条件来验证表的存在?

非常感谢你的帮助。

3 个答案:

答案 0 :(得分:3)

正如其他人所说的那样,你无法用视图实现这一点,因为select语句必须引用一组具体的表 - 如果它们中的任何一个表不存在,那么查询将无法执行。 / p>

在我看来,你的问题更为根本。显然,概念上应该只有一个InvoiceTable,其中包含不同日期的行。按年分成不同的逻辑表大概是为了优化而做的事情(除非列不同,我非常怀疑)。

在这种情况下,partitioning似乎是解决此问题的方法(按年/季/月分区大表是典型的例子)。这将允许您在逻辑上拥有单个InvoiceTable,但指定SQL Server应该在幕后存储数据,就好像它是按年分割的不同表。您可以获得两全其美 - 准确的模型和快速的性能 - 这使您的视图定义变得简单。

答案 1 :(得分:1)

不,根据我的知识,它不可能在视野中,你必须使用存储过程。在存储过程中,您可以验证表存在与否。根据该表的存在,您可以更改SQL。

修改

CREATE PROCEDURE GetYearlySales
AS

IF (EXISTS (SELECT *  
                 FROM INFORMATION_SCHEMA.TABLES  
                 WHERE TABLE_NAME = 'InvoiceTable2013')) 
BEGIN 

   SELECT 2011 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2011 
   UNION ALL 
   SELECT 2012 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2012 
   UNION ALL 
   SELECT 2013 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2013

END
ELSE
BEGIN
   SELECT 2011 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2011 
   UNION ALL 
   SELECT 2012 AS YearNo, ProductID, SUM(Amount) FROM InvoiceTable2012
END 

答案 2 :(得分:0)

看起来您希望每年都有一个表,并且您希望确保在不修改SP的情况下查询SP。这有点风险,您必须始终保持命名约定。在这种情况下,您需要查询table_name的informationschema表,如'InvoiceTable%'。获取表中的记录,然后遍历附加固定SQL的记录。然后执行动态sql,就像在此完成http://www.vishalseth.com/post/2008/07/10/Dynamic-SQL-sp_executesql.aspx

一样