2016-03-18 3 views
1

Все, у меня есть таблица с аналогичными значениями для этого:Получить последнее значение не является «None»

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», это не должна быть равна нулю

заранее спасибо

+2

что я s ваши rdbms ?? \t Пожалуйста, прочитайте [** How-to-Ask **] (http://stackoverflow.com/help/how-to-ask) \t \t И вот отличное место для [** START **] (http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question-on-a-public-forum/), чтобы узнать, как улучшить качество вопроса и получить лучшие ответы. –

+0

Чтобы развернуть комментарий Хуана: полезно отметить вопросы базы данных как с помощью соответствующего программного обеспечения (MySQL, Oracle, DB2, ...) и версии, например. 'SQL-сервер-2014'. Различия в синтаксисе и особенностях часто влияют на ответы. – HABO

ответ

0

Если вы не заботитесь о «с», легкий способ использует 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:

select n.name, t2.serertime, coalesce(t2.value, 0) as value 
from (select distinct name from t) n outer apply 
    (select top 1 t2.servertime, t2.value 
     from t t2 
     where t2.name = n.name and t2.value <> 'None' 
     order by t2.servertime 
    ) t2; 

Я на самом деле нравится этот метод.

+0

Вы получаете '0' за' c'? –

0

SQL Fiddle Demo

Используя только SQL вам нужно создать список всех имен с использованием различны. Затем присоединитесь, чтобы найти 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' 
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') 
Смежные вопросы