如何获取符合我标准的下一行和最近行的值?

时间:2015-03-06 06:26:05

标签: sql sql-server tsql

使用一个表,我必须组合来自两个单独行的值,这样得到的行上的值取决于两个独立行的值的差异。

给出以下示例表:

in_date     out_date    company in_value    out_value
2006-01-01  2006-01-31  ACME    15.03       15.93
2006-01-02  2006-01-31  ACME    14.12       15.85
2006-01-03  2006-01-31  ACME    16.35       14.81
2006-01-04  2006-01-31  ACME    16.06       14.59
2006-01-05  2006-01-31  ACME    16.81       14.07
2006-01-06  2006-01-31  ACME    14.37       16.02
2006-01-07  2006-01-31  ACME    16.36       15.67
2006-01-08  2006-01-31  ACME    15.39       15.01
2006-01-09  2006-01-31  ACME    16.27       15.61
2006-01-10  2006-01-31  ACME    14.45       15.43
2006-01-11  2006-01-31  ACME    16.97       15.45
2006-01-12  2006-01-31  ACME    14.62       15.81
2006-01-13  2006-01-31  ACME    15.11       15.82
2006-01-14  2006-01-31  ACME    14.31       14.34
2006-01-15  2006-01-31  ACME    16.28       15.86
2006-01-16  2006-01-31  ACME    16.40       14.32
2006-01-17  2006-01-31  ACME    14.05       16.94
2006-01-18  2006-01-31  ACME    15.74       14.57
2006-01-19  2006-01-31  ACME    15.79       14.69
2006-01-20  2006-01-31  ACME    15.22       16.14
2006-01-21  2006-01-31  ACME    16.40       16.80
2006-01-22  2006-01-31  ACME    15.22       16.14
2006-01-23  2006-01-31  ACME    16.69       16.79
2006-01-24  2006-01-31  ACME    16.01       14.95
2006-01-25  2006-01-31  ACME    15.28       14.07
2006-01-26  2006-01-31  ACME    15.93       16.47
2006-01-27  2006-01-31  ACME    15.35       14.36
2006-01-28  2006-01-31  ACME    14.92       16.41
2006-01-29  2006-01-31  ACME    15.42       16.04
2006-01-30  2006-01-31  ACME    15.99       15.95
2006-01-31  2006-01-31  ACME    16.75       14.03

我希望得到这样的结果:

in_date     out_date    target_date company in_value    out_value   target_value
2006-01-01  2006-01-31  2006-01-17  ACME    15.03       14.03       16.94

其中:

  • target_valuein_date后第一行的值out_value - in_value > 1
  • target_date分别是in_date的{​​{1}}。

详细信息:

我将始终拥有target_valuein_date。我想得到out_date最终超过out_value的第一个日期1.在示例数据中,如果我在in_value付款,我第一次获得利润1个或多个在2006-01-01上。

代码:

我非常厌恶复杂的查询,所以我只有最基本的查询。

2006-01-17

然而,除了SELECT in_date, out_date, company, in_value, out_value = (SELECT out_value FROM foobar WHERE in_date = '2006-01-31' AND company = 'ACME') FROM foobar WHERE in_date = '2006-01-01' AND out_date = '2006-01-31' AND company = 'ACME' target_date之外,我还提供了所有内容。

问题:

如果target_value在所搜索的行out_value1处于我想要的in_value,我如何获得下一行和最近的行?< / p>

4 个答案:

答案 0 :(得分:1)

你可以使用TOP语法,基本的骨架将是这样的

SELECT TOP 1 * 
From foobar
Where out_value-1 >= all (Select in_value from foo_bar where in_date='2006-01-01')
order by in_date asc;

您可以使用公司名称等添加额外的AND表达式。

答案 1 :(得分:1)

刚刚添加了所需的列。这应该没问题

SELECT   in_date
       , out_date
       , Target_Date = (SELECT TOP 1 in_date 
                    FROM foobar 
                    where out_date-in_date >1 
                    AND in_date = '2006-01-31' 
                    AND company = 'ACME' 
                    ORDER BY in_date
                    )  
       , company
       , in_value
       , out_value   =  (SELECT TOP 1 out_value 
                     FROM foobar 
                     WHERE in_date = '2006-01-31' 
                     AND company = 'ACME') 
       , Target_Value = (SELECT TOP 1 Out_Value 
                    FROM foobar 
                    where out_date-in_date >1 
                    AND in_date = '2006-01-31' 
                    AND company = 'ACME' 
                    ORDER BY in_date)  

FROM foobar
WHERE in_date = '2006-01-01'
AND out_date = '2006-01-31'
AND company = 'ACME'

答案 2 :(得分:1)

尝试使用OUTER APPLY

DECLARE @t TABLE
    (
      in_date DATE ,
      out_date DATE ,
      company CHAR(4) ,
      in_value MONEY ,
      out_value MONEY
    )
INSERT  INTO @t
VALUES  ( '20060101', '20060131', 'ACME', 15.03, 15.93 ),
        ( '20060102', '20060131', 'ACME', 14.03, 14.93 ),
        ( '20060103', '20060131', 'ACME', 13.03, 13.93 ),
        ( '20060104', '20060131', 'ACME', 12.03, 12.93 ),
        ( '20060105', '20060131', 'ACME', 11.03, 11.93 ),
        ( '20060106', '20060131', 'ACME', 10.03, 15.93 ),
        ( '20060107', '20060131', 'ACME', 09.03, 13.93 ),
        ( '20060108', '20060131', 'ACME', 08.03, 16.93 ),
        ( '20060109', '20060131', 'ACME', 07.03, 17.93 ),
        ( '20060110', '20060131', 'ACME', 06.03, 15.93 )



SELECT  t.* ,
        o.out_value AS target_value ,
        o.in_date AS target_date
FROM    @t t
        OUTER APPLY ( SELECT TOP 1
                                t2.out_value,
                                t2.in_date
                      FROM      @t t2
                      WHERE     t2.in_date > t.in_date
                                AND t2.company = t.company
                                AND t2.out_value > t.in_value + 1
                      ORDER BY  in_date
                    ) o
WHERE   t.in_date = '2006-01-01'
        AND t.out_date = '2006-01-31'
        AND t.company = 'ACME'

输出:

in_date     out_date    company in_value    out_value   in_value    target_value    target_date
2006-01-01  2006-01-31  ACME    15.03       15.93       8.03        16.93           2006-01-08

此外,如果删除WHERE子句,您将获得每行的所需结果。

答案 3 :(得分:1)

select * 
from 
(
select t1.*, t2.in_date as t2_in_date, t2.in_value as  t2_in_value,  t2.out_value  as  t2_out_value
     , row_number() order (partition by t1.in_date order by t2.in_date) as rn
  from table t1 
  join tabel t2 
    on t2.in_date   > t1.in_date 
   and t2.out_value > t1.invalue + 1
) as jioned 
where rn = 1