У меня есть данные, которые выглядят так (последний добавленный столбец):
ID Var 1 Date What I Want
aa11 Stage I 1980 Delete
aa11 Stage 2 1980 Keep
aa22 Stage 1 1980 Keep
aa22 Stage 2 1990 Delete
aa33 Stage 3 1992 Keep
Но я хочу, чтобы это выглядело так:
ID Var 1 Date
aa11 Stage 2 1980
aa22 Stage 1 1980
aa33 Stage 3 1992
Мне нужна одна строка данных для каждого идентификатора при следующих условиях: 1. Берутся записи с самыми ранними данными. В противном случае 2. Если в одном году есть две записи, выберите запись с более высокой стадией (var 1). Иначе 3. Возьмите дана единственная запись. Как бы вы вкратце написали фрагмент кода SQL или SAS Data-step?
3 ответа
В SAS это очень просто с шагом данных. Просто отсортируйте данные в нужном порядке, а затем используйте first.id
на шаге данных, чтобы извлечь первый идентификатор. Я предположил, что "Этап I" в вашем сообщении является опечаткой и должен сказать "Этап 1"
/* create original data */
data have;
infile datalines dsd;
input ID $ Var_1 $ Date;
datalines;
aa11,Stage 1,1980
aa11,Stage 2,1980
aa22,Stage 1,1980
aa22,Stage 2,1990
aa33,Stage 3,1992
;
run;
/* sort dataset */
proc sort data=have;
by id date descending var_1;
run;
/* extract first id only */
data want;
set have;
by id;
if first.id;
run;
Я считаю, что здесь можно использовать агрегацию без использования каких-либо переменных, однако сначала я должен сделать одно предположение: - Данные Var 1 можно упорядочить последовательно, то есть: Этап 1 <Этап 2 <Этап 3 и т. Д.
Если это так, вы можете написать следующее, чтобы вернуть то, что вы ищете:
select
ID
--Aggregate results by Max Var1 value
, max(Var1) as Var1
, [Date]
from
[YourTable] a
--Derived Table to return ID and Var1 by lowest Date
inner join
(
select
ID
, Var1
, min([Date]) as [Date]
from
[YourTable]
group by
ID
, Var1
) b on a.ID = b.Id
group by
Id
, [Date]
В случае, если для этого идентификатора будет возвращено только одно значение, поскольку оно имеет как значение MIN Date, так и значение Max Var1.
Это приоритетный запрос. Это сложно. Вот метод с использованием переменных для перечисления строк:
select t.*
from (select t.*,
(@rn := if(@id = id, @rn + 1,
if(@id := id, 1, 1)
)
) as seqnum
from t cross join
(select @rn := 0, @id := '') params
order by id, year asc, var1 asc
) t
where seqnum = 1;
Логика приоритезации обрабатывается предложением order by
. Строки пронумерованы для каждого id
на основе дополнительных ключей. Затем внешний запрос берет первую встреченную строку.
Похожие вопросы
Новые вопросы
mysql
MySQL — это бесплатная система управления реляционными базами данных (RDBMS) с открытым исходным кодом, которая использует язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. д. Это разные БД, которые используют свои собственные диалекты SQL для управления данными. В вопросе всегда указывайте точную версию сервера. Версии 5.x сильно отличаются по своим возможностям от версий 8+.