2014-01-21 2 views
4

Я следующий набор данных:SAS отчетливые в Proc SQL против прок рода nodupkey

data work.dataset; 
input a b c; 
datalines; 
27 93 71 
27 93 72 
46 68 75 
55 55 33 
46 68 68 
34 34 32 
45 67 88 
56 75 22 
34 34 32 
; 
run; 

Я хочу, чтобы выбрать все различные записи из первых 2-х колонок, так что я писал:

proc sql; 
create table work.output1 as 
select distinct t1.a, 
t1.b 
from work.dataset t1; 
quit; 

Но теперь я хотите знать, какое значение var c стоит в предыдущем наборе рядом с комбинацией (var a, var b), которая видна на выходе. Есть ли способ узнать? Я попытался выполнить сортировку proc, но я не знаю, работает ли она так же, как выбор отдельных записей в proc sql.

proc sort data = work.dataset out = work.output2 NODUPKEY; 
by a b; 
run; 

Благодарим за помощь.

ответ

1

NODUPKEY вернет одно наблюдение за каждым ключом. В вашем примере будет сохранено только одно из двух наблюдений с a = 27 и b = 93. Либо c = 71, либо c = 72 будут потеряны.

Опция NODUPREC удаляет повторяющиеся записи. Оба наблюдения с a = 27 и b = 93 будут сохранены, но только один из двух со значениями a = 34, b = 34 и c = 32.

+0

Я знал это, но вопрос в том, можно ли узнать, какой из них (c = 71 или c = 72) был сброшен. Я предполагаю, что SAS ведет запись, которая является «более высокой» в наборе данных (в этом примере укротителя 27 93 71 будет сохранена), но нужен кто-то, кто либо подтверждает, либо отрицает это. – user2280549

+1

В sql выберите отдельный запрос, никакая запись не будет удалена, так как переменная c не является частью выбора. В примере proc sort nodupkey SAS сохраняет только первое наблюдение, с которым он сталкивается. –

+0

Спасибо за ответы. Еще один, возможно ли сделать proc sql, взяв n столбцов и «отличая» его на основе только их подмножества? Другими словами, я бы добавил row_number к моим данным, выберите a, b и row_number, но отдельная функция будет помещена в первые два столбца. – user2280549

3

PROC SORT с NODUPKEY всегда будет возвращать физическую первую запись - то есть, когда вы перечислите данные, c=71 будет храниться всегда. PROC SQL не обязательно будет возвращать какую-либо конкретную запись; вы можете запросить min или max, но вы не можете гарантировать первую запись в порядке сортировки независимо от того, как вы сделали запрос; SQL часто прибегает к данным по мере необходимости, чтобы выполнить запрос как можно более эффективно.

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

Вы не можете выполнить одно и то же прямолинейно в SQL; потому что SQL не имеет понятия упорядочения строк, вам придется либо выбрать способ, с помощью которого c (max(c), min(c) и т. д.), либо вам нужно будет добавить счетчик строк и выбрать самое низкое значение этого.

Например:

data work.dataset; 
input a b c; 
rowcounter=_n_; 
datalines; 
27 93 71 
27 93 72 
46 68 75 
55 55 33 
46 68 68 
34 34 32 
45 67 88 
56 75 22 
34 34 32 
; 
run; 

proc sql; 
select a,b,min(rowcounter*100+c)-min(rowcounter*100) as c 
from work.dataset 
group by a,b; 
quit; 

Вот с помощью чита (зная, что rowcounter * 100 всегда будет доминировать размер с); конечно, если ваш c не имеет значений, подходящих для этого, это не сработает, и вам лучше слить его отдельно.

Если вас интересует решение SQL, вы можете рассмотреть вопрос о том, что это явно как отдельный вопрос, так как пользователь SQL-only ответит на него.

0

Sql не возвращает значение переменной c в указанном выше запросе, так как оно не указано в инструкции select. Я думаю, что вы можете искать это:

proc sql; 
create table work.output1 as 
select t1.a, 
t1.b, 
min(t1.c) as c 
from work.dataset t1 
group by a, b; 
quit; 

Если вы хотите максимальное значение c, то вы можете заменить функцию с max(t1.c) as c, или использовать любого из других SQL функций для того, чтобы выбрать значение. Если вы хотите реплицировать PROC SORT nodupkey и перенести первое значение в список, вам нужно будет использовать функцию монотонную (я знаю ... не поддерживается SAS, но она там так и есть).Ваш код будет выглядеть следующим образом:

proc sql; 
create table work.output1 as 
select monotonic() as rownum, 
t1.a, 
t1.b, 
t1.c 
from work.dataset t1 
group by a, b 
having calculated(rownum) = min(calculated rownum); 
quit;