首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >T-SQL:创建基于先前值的查找和计算的列。

T-SQL:创建基于先前值的查找和计算的列。
EN

Stack Overflow用户
提问于 2014-08-24 21:31:24
回答 3查看 124关注 0票数 2

我希望有人能为我编写一个返回计算值的查询指明正确的方向,该值使用查找来查找以前的值。例如,我有两个表,如下所示。我在视图中将它们结合在一起,但我需要添加一个额外的列,该列为我提供了一个以前的值:

CEO_Table:

代码语言:javascript
复制
CEO_Name      | FromDate   | ToDate       
-----------------------------------------
Glen Bryant   | 2000-11-30 | 2002-06-30
Bob Costa     | 2002-6-30  | 2004-9-15  
Gill Bogart   | 2004-9-15  | 2009-10-01  
Ben Olson     | 2009-10-01 | 2010-08-10  

Expense_Table:

代码语言:javascript
复制
Date       | AsOf_Expenses_Total_Millions (as Exp)
-----------------------------------------
2001-01-01 | 100
2002-01-01 | 300
2003-01-01 | 155
2004-01-01 | 350
2005-01-01 | 400
2006-01-01 | 600
2007-01-01 | 150
2008-01-01 | 200
2009-01-01 | 300
2010-01-01 | 500

我试图使用这两个表来构造一个视图,添加三个额外的列: CEO (查找指定日期的首席执行官);LastCEOExp (查找前任首席执行官的上一个费用值);PercentChange (使用LastCEOExp计算百分比变化,使用公式(Exp - LastCEOExp)/(LastCEOExp) * 100)。

CEO_Expenses_Change_Over_Time:

代码语言:javascript
复制
Date       | Exp | CEO_Name      | LastCEOExp | PercentChange
-------------------------------------------------------------------
2001-01-01 | 100 | Glenn Bryant  | NULL       | NULL
2002-01-01 | 300 | Glenn Bryant  | NULL       | NULL
2003-01-01 | 155 | Bob Costa     | 300        | -48%
2004-01-01 | 350 | Bob Costa     | 300        | 16%
2005-01-01 | 400 | Gill Bogart   | 350        | 14%
2006-01-01 | 600 | Gill Bogart   | 350        | 71%
2007-01-01 | 150 | Gill Bogart   | 350        | -57%
2008-01-01 | 200 | Gill Bogart   | 350        | -42%
2009-01-01 | 300 | Gill Bogart   | 350        | -14%
2010-01-01 | 500 | Ben Olson     | 300        | 66%

我已经添加了CEO_Name列,但是LastCEOExp列有问题。一旦我确定了那个列,我就可以自己把PercentChange列放在一起了。有人有什么建议吗?我猜想我可以用一个CTE来完成这个任务,但是我不知道从哪里开始。以下是我所拥有的:

代码语言:javascript
复制
SELECT exp.[Date]
  ,exp.[Exp]
  ,ceo.[CEO_Name]
FROM [Expense_Table] exp
INNER JOIN [CEO_Table] ceo
ON exp.[Date] between ceo.[FromDate] and ceo.[ToDate]
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-08-25 21:48:46

您需要熟悉Server中的窗口函数。这里有一个解决方案:

代码语言:javascript
复制
WITH
    tmp AS
    (
        SELECT      exp.Date,
                    CEO_Name,
                    exp.Exp,
                    DENSE_RANK() OVER (ORDER BY ceo.FromDate)       AS CEOOrder,
                    ROW_NUMBER() OVER (PARTITION BY ceo.CEO_Name ORDER BY exp.Date DESC)
                                                                    AS ExpOrder
        FROM        CEO_Table       ceo
        INNER JOIN  Expense_Table   exp     ON exp.Date BETWEEN ceo.FromDate AND ceo.ToDate
    )

SELECT      t1.Date,
            t1.CEO_Name,
            t1.Exp,
            t2.Exp                              AS LastCEOExp,
            (t1.Exp - t2.Exp) / t2.Exp * 100    AS PercentChange
FROM        tmp     t1
LEFT JOIN   tmp     t2  ON t1.CEOOrder = t2.CEOOrder + 1  -- This select the last CEO
                       AND t2.ExpOrder = 1                -- This select his last pay
ORDER BY    t1.CEOOrder, t1.ExpOrder DESC

SQL Fiddle

票数 0
EN

Stack Overflow用户

发布于 2014-08-25 17:50:02

我做了这样的代码,我用

ROW_NUMBER (Transact-SQL) http://msdn.microsoft.com/en-us/library/ms186734.aspx

在您的示例中,ROW_NUMBER可能会随着时间的推移而变化,然后使用ROW_ID,您可以创建函数返回表SHIFT+1 ROW_ID,然后加入这些表,注意,当您使用临时表、视图时,需要在ROW_ID上添加大型集合的索引。

第二个选项是创建函数(参数日期时间),返回值将适用于小集合。

代码语言:javascript
复制
SELECT A.*,PrevYear.*, cast(( ROUND((cast(A.[Exp] as float) - cast(PrevYear.[Exp] as float) ) / cast(A.[Exp] as float) * 100  ,2) ) as varchar) + '%' as  PercentChange from
(SELECT ROW_NUMBER() OVER(ORDER BY exp.[Date] DESC) AS Row, exp.[Date]
  ,exp.[AsOf_Expenses_Total_Millions] as [Exp]
  ,ceo.[CEO_Name]
FROM [Expense_Table] exp
INNER JOIN [CEO_Table] ceo
ON exp.[Date] between ceo.[FromDate] and ceo.[ToDate]
) A left join


(SELECT (ROW_NUMBER()  OVER(ORDER BY exp.[Date] DESC) -1) AS Row, exp.[Date]
  ,exp.[AsOf_Expenses_Total_Millions] as [Exp]
  ,ceo.[CEO_Name] as PrevCEO_Name
FROM [Expense_Table] exp
INNER JOIN [CEO_Table] ceo
ON exp.[Date] between ceo.[FromDate] and ceo.[ToDate]
) PrevYear

on A.row = PrevYear.row
order by A.row
票数 0
EN

Stack Overflow用户

发布于 2014-08-25 20:52:45

我认为领导/滞后可能会让你得到你想要的东西:

If object_id(N‘’tempdb.##not_table‘,N’u‘)是非空的。

  drop table ##lag_table;

create table ##lag_table (

(1,1)

准的,准模型

(9,2)

再创造

(B)主要用途);

insert into ##lag_table

(N‘’modelA‘,10,N’2013-01‘)

(n‘模式A’,5,N‘2011-01’)

(n‘模式A’,2,N‘2009-01’);

--

-暗码转码块端

--

-相应代码块开始

选择次id

自愿性

(C)再分配;再分配;

(1).

自愿

自愿性的、自愿的、自愿的、直接的、自愿的、自愿的

(C).

自愿

自愿性、自愿性

from   ##lag_table;

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25476504

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档