在SQL中选择最新条目

时间:2014-10-27 14:43:39

标签: sql select sql-server-2008-r2 greatest-n-per-group

我试图从SQL中的数据集中选择最近的非零条目。大多数这样的例子都满足于仅通过变量返回日期和组,但我还想返回相关的值。例如:

ID       Date          Value
----------------------------
001      2014-10-01     32
001      2014-10-05     10
001      2014-10-17      0
002      2014-10-03     17
002      2014-10-20     60
003      2014-09-30     90
003      2014-10-10      7
004      2014-10-06    150
005      2014-10-17      0
005      2014-10-18      9

使用

SELECT ID, MAX(Date) AS MDate FROM Table WHERE Value > 0 GROUP BY ID

返回:

ID       Date      
-------------------
001      2014-10-05
002      2014-10-20
003      2014-10-10
004      2014-10-06
005      2014-10-18

但每当我尝试将Value包含为所选变量之一时,SQLServer都会导致错误:

  

"专栏'价值'在选择列表中无效,因为它不是   包含在聚合函数或GROUP BY子句中。"

我想要的结果是:

ID       Date          Value
----------------------------
001      2014-10-05     10
002      2014-10-20     60
003      2014-10-10      7
004      2014-10-06    150
005      2014-10-18      9

我想到的一个解决方案是在原始表格中查找结果并返回与相关ID相对应的值。日期(我已经减少了,所以我知道这些是独一无二的),但在我看来这似乎是一个混乱的解决方案。任何有关这方面的帮助将不胜感激。

注意:我不想按值分组,因为这是我最终想要提取的结果(即对于每个ID,我想要最新的值)。进一步的例子:

ID       Date          Value
----------------------------
001      2014-10-05     10
001      2014-10-06     10
001      2014-10-10     10
001      2014-10-12      8
001      2014-10-18      0

在这里,我只想要最后一个非零项。 (001,2014-10-12,8)

SELECT ID, MAX(Date) AS MDate, Value FROM Table WHERE Value > 0 GROUP BY ID, Value

会回来:

ID       Date          Value
----------------------------
001      2014-10-10     10
001      2014-10-12      8

5 个答案:

答案 0 :(得分:3)

这也可以使用窗口函数来完成,该窗口函数比分组查询的连接速度快得多:

select id, date, value
from (
  select id,
         date,
         value,
         row_number() over (partition by id order by date desc) as rn
  from the_table
) t
where rn = 1
order by id;

答案 1 :(得分:1)

假设您没有表中相同ID的重复日期,这应该有效:

SELECT A.ID, A.Date, A.Value
FROM
   T1 AS A
   INNER JOIN (SELECT ID,MAX(Date) AS Date FROM T1 WHERE Value > 0 GROUP BY ID) AS B
      ON A.ID = B.ID AND A.Date = B.Date

答案 2 :(得分:1)

select a.id, a.date, a.value from Table1 a inner join (

select id, max(date) mydate from table1 
where Value>0 group by ID) b on a.ID=b.ID and a.Date=b.mydate

答案 3 :(得分:0)

使用Subqry,

SELECT  ID, Date AS MDate, VALUE 
FROM    table  t1
where   date = (Select max(date)
                from    table t2
                where   Value >0
                and     t1.id = t2.id
                )

答案 4 :(得分:0)

提供的答案非常合适,但使用CTE:

;WITH cteTable
AS
(
  SELECT
    Table.ID [ID], MAX(Date) [MaxDate]
  FROM
    Table
  WHERE
    Table.Value > 0
  GROUP BY
    Table.ID
)

SELECT
    cteTable.ID, cteTable.Date, Table.Value
FROM
    Table INNER JOIN cteTable ON (Table.ID = cteTable.ID)