2015-08-05 2 views
1

В базе данных у нас есть набор адресов электронной почты, как показано ниже. Пожалуйста, обратите внимание, что есть два наблюдения для ид 1003заявление об обновлении на этапе данных

data Email; 
    input id$ email $20.; 
    datalines; 
1001 [email protected] 
1002 [email protected] 
1003 [email protected] 
1003 [email protected] 
; 
run; 

И мы получаем запрос пользователя, чтобы изменить адрес электронной почты в следующем,

data amendEmail; 
    input id$ email $20.; 
    datalines; 
1003 [email protected] 
; 
run; 

попытку использования update заявления на этапе данных

data newEmail; 
    update Email amendEmail; 
    by id; 
run; 

Хотя это только изменение первого наблюдения для идентификатора 1003.

Мой желаемый результат будет 1001 [email protected] 1002 [email protected] 1003 [email protected] 1003 [email protected]

возможно с применением не ргос метод SQL?

+0

Извините, каков ваш вопрос в точности? Вы хотите изменить обе строки? (в этом случае вы просто закончите с дублированной строкой) – Longfish

ответ

1

Если вы хотите изменить оба ряда, вы получите дубликаты. Вероятно, вы должны решить проблему дубликатов в исходной таблице.

Если вам нужно рабочее решение с дублирующимися результатами, рассмотрите возможность использования PROC SQL с LEFT JOIN и условным предложением для адреса электронной почты.

PROC SQL; 
    CREATE TABLE EGTASK.QUERY_FOR_EMAIL AS 
     SELECT t1.id, 
      /* email */ 
      (CASE WHEN t1.id = t2.id THEN t2.email 
      ELSE t1.email 
      END) AS email 
     FROM WORK.EMAIL t1 
     LEFT JOIN WORK.AMENDEMAIL t2 ON (t1.id = t2.id); 
QUIT; 

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

data want (drop=email2); 
    merge Email amendEmail (rename=(email=email2)); 
    by id; 
    if email2 ne "" then email=email2; 
run; 
+0

Большое спасибо за ответ! Мне интересно, может ли это сделать шаг без данных sql sql? – useR

+0

@useR Конечно, см. Отредактированный мной комментарий. –

2

слияния на основе данных шаг ответ Vasilij даст вам набор данных вы хотите, но не наиболее эффективным способом, поскольку он перезапишет весь набор данных email, вместо того, чтобы обновлять только строки, которые вы хотите изменить.

Вы можете использовать оператор modify, чтобы изменить адрес электронной почты только для строк от email с соответствующими идентификаторами в наборе данных amendEmail.

Во-первых, вам необходимо иметь индекс на id в наборе данных email. Это просто одноразовое задание - если вы не перезаписываете набор данных email (например, с помощью другого шага данных, который не использует оператор modify, или путем его сортировки), индекс все равно будет там.

proc datasets lib = work nolist; 
    modify email; 
    index create id; 
    run; 
quit; 

Теперь вы можете делать обновления с помощью индекса:

data email; 
    set amendEmail(rename = (email = new_email)); 
    do until(eof); 
     modify email key = id end = eof; 
     if _IORC_ then _ERROR_ = 0; 
     else do; 
      email = new_email; 
      replace; 
     end; 
    end; 
run; 

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

NOTE: There were 1 observations read from the data set WORK.AMENDEMAIL. 
NOTE: The data set WORK.EMAIL has been updated. There were 2 observations rewritten, 0 observations added and 0 observations 
     deleted. 

NB прежде чем использовать инструкцию modify, выполните следующие действия: убедитесь, что ваш мастер email dataset резервную копию.Если шаг данных прерван, он может стать поврежденным.

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