获取不是“无”的最后价值

时间:2016-03-18 21:06:00

标签: sql tsql

全部,我有一张与此类似的值的表:

Name    Value   Server time
a   None    3/17/2016 11:59:50 PM
a   None    3/17/2016 11:59:36 PM
a   None    3/17/2016 11:59:33 PM
a   March Madness   3/17/2016 11:59:33 PM
a   None    3/17/2016 11:59:19 PM
b   TGIF    3/17/2016 11:59:04 PM
b   None    3/17/2016 11:58:44 PM
b   March Madness   3/17/2016 11:58:29 PM
b   None    3/17/2016 11:58:22 PM
c   None    3/17/2016 11:58:17 PM
c   None    3/17/2016 11:58:15 PM
c   None    3/17/2016 11:58:14 PM
c   None    3/17/2016 11:57:50 PM
c   None    3/17/2016 11:57:33 PM

我的结果集应为:

a   March Madness
b   TGIF
c   0

换句话说,我应该得到ServerTime排序的最新值,不是'None',当我只有'None'时,它应该为零

提前致谢

3 个答案:

答案 0 :(得分:0)

如果您不关心“c”,一种简单的方法是使用string-match-p子句:

where

如果您确实想要所有名称,那么您可以使用聚合方法:

select t.*
from t
where t.servertime = (select max(t2.server_time)
                      from t t2
                      where t2.name = t.name and t2.value <> 'None'
                     );

甚至select name, max(case when t.value <> 'None' then servertime end), max(case when t.value <> 'None' and seqnum = 1 then value end) from (select t.*, row_number() over (partition by name order by (case when t.value = 'None' then 1 else 2 end) desc, servertime desc ) as seqnum from t ) t group by name;

outer apply

我其实喜欢这种方法。

答案 1 :(得分:0)

<强> SQL Fiddle Demo

只使用SQL,您需要使用distinct创建每个Name的列表。然后加入以查找每个名称的MAX(服务器时间)。然后第三次加入以获得价值。最后,NULL变为0,与c

的情况类似
SELECT S."Name", 
       T.mtime, 
       CASE WHEN T.mtime IS NULL THEN '0'
                                 ELSE YT."Value"
       END as Value
FROM (
      SELECT  DISTINCT YT."Name"
      FROM YourTable YT
      ) S
LEFT JOIN (
           SELECT "Name", MAX("Server time") as mtime
           FROM YourTable
           WHERE "Value" <> 'None'
           GROUP BY "Name"
           ) T
    ON S."Name" = T."Name"
LEFT JOIN  YourTable YT
   ON YT."Server time" = T.mtime
  AND YT."Value" <> 'None'

<强>输出

| Name |                   mtime |         value |
|------|-------------------------|---------------|
|    a | March, 17 2016 23:59:33 | March Madness |
|    b | March, 17 2016 23:59:04 |          TGIF |
|    c |                  (null) |             0 |

另一个少JOIN的解决方案,创建一个虚拟日期来解决C案例

SELECT TM."Name", 
       TM.mtime, 
       CASE WHEN T."Value" IS NULL THEN '0'
                                   ELSE T."Value"
       END as Value
FROM ( 
           SELECT "Name", MAX(CASE WHEN t."Value" <> 'None' THEN "Server time"
                                                            ELSE '0001-1-1 0:0:0'
                              END) as mtime
           FROM YourTable t          
           GROUP BY "Name"
      ) TM
LEFT JOIN YourTable T
  ON TM."Name" = T."Name"
 AND (TM.mtime = T."Server time" )
 AND T."Value" <> 'None'

答案 2 :(得分:0)

select name, value  
from 
( select name, value 
       , row_number() over (partition by name, order by servertime desc) as rn 
    from table 
   where name <> 'None' 
) tt
where rn = 1 
union 
select name, '0' as 'value' 
from table 
where not exists (select 1 from table where name <> 'None')