2009-06-10 36 views
0

我不喜欢在两个地方定义相同的东西,如果我能避免它。我认识到下面的两个查询处理两个不同的表,但这些表基本上拥有相同类型的数据(不同的谓词保证两个查询),我认为下面的两个投影是“定义相同的东西在两个地方“。重构SQL投影?

当/如果我在以后修改这些查询,包括不同的栏目,我敢肯定,我会永远想的预测保持一致。

假设,并且不使用动态SQL,并没有“*”在任何投影(在我的生产环境不允许的),我可以定义“columnset”一次,在这两个查询使用它?

SELECT columnA 
    , columnB 
    , columnC 
FROM Data 

SELECT columnA 
    , columnB 
    , columnC 
FROM DataArchive 
+0

你有数据存储在两个地方。无论如何,为了检索任何给定调用所需的数据,您需要知道要从中检索哪组数据。发布的SELECT ... UNION ALL ...解决方案只会导致需要一个查询,但您需要添加“开关”来控制实际查询的集合。你可以把它添加到你的代码库吗?我更喜欢Blixt的视图实现,但我也建议考虑将这些表合并成一个表。 (这听起来像是“当前/小型/常用套装与历史/极度/罕用套装”的情况,但你永远不知道。) – 2009-06-10 18:27:20

回答

1

有你的基地,在数据和DataArchive的工会和使用内联表值函数(SQL Server 2005和了)?

CREATE FUNCTION UnifiedData (@LiveOnly bit, @ArchiveOnly bit) 
RETURNS TABLE 
AS 
RETURN (
    SELECT columnA 
      ,columnB 
      ,columnC 
    FROM (
     SELECT 'Live' AS Src, * 
     FROM Data 
     WHERE @ArchiveOnly = 0 

     UNION ALL 

     SELECT 'Archive' AS Src, * 
     FROM DataArchive 
     WHERE @LiveOnly = 0 
    ) 
) 

不是很好,但应该由优化器处理,因为它已被内联。

+0

我喜欢它。我现在在问题中加入了'*'禁止。我最初没有包括它的道歉。 – lance 2009-06-10 16:18:14

0

我想不出有效的方法。当然,你可以使用两个表中的UNION ALL进行查看,并添加一个将表名保存为字符串的列,然后执行SELECT columnA, columnB, columnC FROM view WHERE table = 'Data',但感觉像是一个相当丑陋的黑客攻击。

0

呀,SQL是可怕的这种方式。没有全面的令人满意的方式来做到这一点。以下是使用同义词的示例:

if object_id('DataSynonym') is not null drop synonym DataSynonym 
create synonym DataSynonym for Data 
select columnA, columnB, columnC from DataSynonym 

if object_id('DataSynonym') is not null drop synonym DataSynonym 
create synonym DataSynonym for DataArchive 
select columnA, columnB, columnC from DataSynonym 

这种使用同义词的问题是它们在全局范围内。如果您在一个连接中即时重新定义同义词,则会影响所有其他连接上的用户。

临时视图/函数或视图/函数变量会走很长的路来解决这个问题。或者像SAS中可用的宏语言。

0

创建的数据UNION ALL DataArchive视图。如果您稍后能够重构和合并这两个表格,这对您现有的查询将是透明的。