2013-08-01 3 views
1

У меня есть следующие данные:Получить последние изменения переменной в соответствии с временной меткой

data have; 
    input username $ betdate : datetime. customerCode; 
    dateOnly = datepart(betdate) ; 
    format betdate DATETIME.; 
    format dateOnly ddmmyy8.; 
    datalines; 
    player1 12NOV2008:12:04:01 1 
    player1 04NOV2008:09:03:44 10 
    player2 07NOV2008:07:03:33 1 
    player2 05NOV2008:09:00:00 0.5 
    player3 05NOV2008:09:05:00 1 
    player2 07NOV2008:14:03:33 1 
    player1 05NOV2008:09:00:05 20 
    player2 07NOV2008:16:03:33 1 
    player2 07NOV2008:18:03:33 1 
    player2 09NOV2008:10:05:10 0.7 
    player3 15NOV2008:15:05:33 10 
    player3 15NOV2008:15:05:33 1 
    player2 15NOV2008:15:05:33 0.1 
run; 
PROC PRINT; RUN; 

Как я могу запустить «ргос SQL» команду, чтобы вытащить последний (то есть отчетливое (customerCode каждого игрока) с (т. е. max (betdate) и обновление самого последнего игрока (по betdate) для customerCode? Это динамическая переменная, которая время от времени меняется? Должен ли я запускать подзадачу для каждого имени пользователя, ища max (betdate) и customerCode из таблицы?

+0

Добавлено SQL тегов, чтобы вы могли получить лучшие ответы от SQL экспертов – Joe

ответ

1

PROC SQL - это не самый простой способ сделать это, но это, безусловно, возможно.

proc sql; 
select H.username, H.customercode from have H inner join (
    select username, max(betdate) as maxdate from have group by username 
) V 
on H.username=V.username and H.betdate=V.maxdate; 
quit; 

Это возвращает два значения для Player3, вам нужно будет решить, как разрешать связи. Шаг данных намного проще, хотя требуется не более одного сорта и одного прохода (а в хеше будет еще быстрее или в матрице IML).

+0

Это работает отлично. Наблюдение с дубликатом betdate для игрока3 выше было опечаткой с моей стороны, поэтому я изменил его. Я пытаюсь реплицировать ваш код с помощью подзадача, а не с помощью innerjoin, так как это упростит, например, вытащить первое и последнее значения для customerCode, но оно не будет оцениваться в одиночной строке на игрока ! 'proc sql; выберите имя пользователя, (выберите V.customercode from have V, где V.username = H.username и V.betdate = \t (Выберите max (X.betdate) из X, где X.username = H.username)) из группы H по имени пользователя; quit; ' – user2146441

+0

Это не будет решаться до одного, если у вас есть связи, как я заметил - вам нужно выяснить, как их решить. – Joe

1

Вы можете использовать функцию proc sql, известную как агрегирование, с "remerging". Следующий запрос выводит каждую строку с максимальной датой по имени пользователя:

proc sql; 
select H.username, H.customercode, date, max(date) as maxdate 
from have H 
group by H.username 
quit; 

Вы можете поместить это в подзапросе, чтобы получить нужные значения:

proc sql; 
select username, customercode, date 
from (select H.username, H.customercode, date, max(date) as maxdate 
     from have h 
     group by H.username 
    ) h 
where date = maxdate; 
quit; 

Следующие может также работать, но я не имеют SAS под рукой, чтобы проверить, где я сейчас нахожусь:

proc sql; 
    select H.username, H.customercode, date 
    from have H 
    group by H.username 
    having date = max(date) 
quit; 
+0

Одна нота - remerging в основном SAS-only, я не знаю никаких других SQL-аксессуаров, которые позволят вам получить это автоматическое слияние (или позволить вам выбирать вещи, не входящие в группу, или агрегировать функции). – Joe

+0

@Joe. , , Первая часть вашего утверждения верна (это одно из многих различий между «proc sql» и другими диалектами SQL). Вторая часть неверна. MySQL поддерживает столбцы не в разделе 'group by', как и некоторые версии Postgres. Эта функциональность даже согласуется с более поздними версиями стандарта ANSI (хотя результат сильно отличается от того, что производит proc SQL). –

+0

Ну, я знаю/использую SQL Server и Oracle, так что это было технически верно;) Спасибо за разъяснение. – Joe

Смежные вопросы