T-SQL视图 - CTE + UNPIVOT与UNION及其他技术的比较

3

我想知道哪种方法更好。我需要在视图中声明一些变量,这些变量使用 T-SQL 日期函数进行计算(DATEADD、DATEPART、GETDATE() 等)。

经过一些研究,我写出了以下代码:

WITH DatePeriods(ThisWeek,LastWeek,MonthToDate,QuarterToDate,YearToDate) AS
(
    SELECT  "...date functions..." AS ThisWeek
            "...date functions..." AS LastWeek
            "...date functions..." AS MonthToDate
            "...date functions..." AS QuarterToDate
            "...date functions..." AS YearToDate
)
SELECT Desciption,Value
FROM DatePeriods
UNPIVOT
(
    Value FOR Desciption IN (ThisWeek,LastWeek,MonthToDate,QuarterToDate,YearToDate)
) AS Source

如果我使用“cte”和“unpivot”,看起来很酷。如果我想添加其他日期变量,我只需要在CTE的选择中插入即可。

另一种解决方案是使用普通的“union”:

SELECT  'ThisWeek',"...date functions..." AS ThisWeek
UNION
SELECT  'LastWeek',"...date functions..." AS LastWeek
UNION
SELECT  'MonthToDate',"...date functions..." AS MonthToDate
UNION
SELECT  'QuarterToDate',"...date functions..." AS QuarterToDate
UNION
SELECT  'YearToDate',"...date functions..." AS YearToDate

我认为这不太好,因为新的日期变量意味着新的联合,但毕竟只有少数变量之间的联合。

有人可以告诉我在这种情况下哪种技术是最佳实践,甚至提供其他解决方案吗?

提前感谢。

编辑:

这是我想要的输出:

Desciption      Value
ThisWeek        2012-08-05 08:55:23.013
LastWeek        2012-07-29 08:55:23.013
MonthToDate     2012-07-08 08:55:23.013
QuarterToDate   2012-05-08 08:55:23.013
YearToDate      2011-08-08 08:55:23.013

你检查了两个查询的执行计划吗? - Taryn
@bluefeet 是的,我看过了,但是当涉及到比较执行计划时,我并不是真正的专家。此外,在每个查询执行期间会发生很多事情,但它们都执行了0秒。而且计划中几乎每个项目的成本都为0%。 - gotqn
1个回答

5
如果您查看查询计划,您会发现您的union版本比您的unpivot版本成本高得多。但是,如果您改为使用union all,它将优于unpivot
如果您使用的是SQL Server 2008或更高版本,则可以使用values代替,根据执行计划,成本与union all相同。 values版本:
select Description, Value
from (values ('ThisWeek',      getdate()+1),
             ('LastWeek',      getdate()+2),
             ('MonthToDate',   getdate()+3),
             ('QuarterToDate', getdate()+4),
             ('YearToDate',    getdate()+5)
     ) as T(Description, Value)

Union all版本:

SELECT  'ThisWeek' AS Description, getdate()+1 AS Value
UNION ALL
SELECT  'LastWeek', getdate()+2
UNION ALL
SELECT  'MonthToDate', getdate()+3 
UNION ALL
SELECT  'QuarterToDate', getdate()+4 
UNION ALL
SELECT  'YearToDate', getdate()+5
< p > unionunion all 慢的原因是它尝试从结果集中删除重复项,而 union all 则包含所有行而不考虑值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接