2014-08-27 5 views
3

У меня есть довольно простой SQL, который должен обеспечивать 1 строку за квартал за 1 ресурс1. Вместо этого я получаю несколько строк в каждой группе.SAS proc sql, возвращающий повторяющиеся значения группы по/по переменным

Ниже приведен SQL, шаг данных SAS и некоторые выходные данные. Количество повторяющихся строк (в приведенных ниже данных, 227708) равно Num_borrowers, что является номером количества элементов 1.

proc sql outobs=max; 

create table table1 as 
select 
    case 
     when period_dt ='01DEC2003'd then '2003Q4' 
     when period_dt ='01DEC2004'd then '2004Q4' 
     when period_dt ='01DEC2005'd then '2005Q4' 
     when period_dt ='01DEC2006'd then '2006Q4' 
     when period_dt ='01DEC2007'd then '2007Q4' 
     when period_dt ='01DEC2008'd then '2008Q4' 
     when period_dt ='01DEC2009'd then '2009Q4' 
     when period_dt ='01DEC2010'd then '2010Q4' 
     when period_dt ='01DEC2011'd then '2011Q4' 
     when period_dt ='01DEC2012'd then '2012Q4' 
     when period_dt ='01DEC2013'd then '2013Q4' 
     when period_dt ='01JUN2014'd then '2014Q2' 
    end as QTR, 
    case 
     when MM_ASSET in ('C&I', 'Foreign', 'Leasing','Scored-WF','Scored-WB') THEN 'C&I' 
     when MM_ASSET='Construction' THEN 'Construction RE' 
     when MM_ASSET='Mortgage-IP' THEN 'Income Producing RE' 
     when MM_ASSET='Mortgage-OO' THEN 'Owner Occupied RE' 
     when MM_ASSET='Mortgage-SF' THEN 'Mortgage-SF' 
     when MM_ASSET='Unknown' THEN 'Other' 
    end as asset1, 
    count (period_dt) as Num_Borrowers, 
    exposure, 
    co_itd, 
    MM_NINEQTR_LOSS, 
    MM_LIFE_LOSS 
    from td_prod.OBLIGOR_COMBINED 
    where period_dt in ('01DEC2003'd,'01DEC2004'd,'01DEC2005'd,'01DEC2006'd,'01DEC2007'd,'01DEC2008'd, '01DEC2009'd,'01DEC2010'd,'01DEC2011'd,'01DEC2012'd,'01DEC2013'd,'01JUN2014'd) 
    and mm_asset in ('C&I','Foreign','Leasing','Construction','Mortgage-IP','Scored-WF','Scored-WB' 
       'Mortgage-OO','Mortgage-SF','Unknown') 
    group by 1,2 
    order by 1,2; 

quit; 



data table2; set table1; 

    Total_Exposure = exposure/1000000; 
    if total_exposure = 0 then total_exposure=.; 
    Total_Charge_Offs =co_itd/1000000; 
    Total_9Q_Losses = MM_NINEQTR_LOSS/1000000; 
    Total_Life_Losses = MM_LIFE_LOSS/1000000; 
    avg_borrower_exp = total_exposure/num_borrowers; 
    co_rate = total_charge_offs/total_exposure; 
    life_lossR = Total_life_losses/total_exposure; 
    nineQtr_lossR = total_9q_losses/total_exposure; 

run; 



*** sample of output data set ***; 
qtr    asset1  num_borrowers 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
2003Q4   C&I    227708 
+0

какой базы данных вы используете здесь? Кажется MySQL, вы выбираете больше полей в неагрегатной форме, чем вы группируете. Как ваша база данных знает, как обрабатывать несколько комбинаций воздействия, co_itd, MM_NINEQTR_LOSS, MM_LIFE_LOSS ? – Twelfth

+4

Предположим, что используется SAS, за тег и PROC SQL. SAS SQL делает нечетную стандартную вещь, отличную от ANSI, когда вы помещаете столбец в оператор select, который не является одним из столбцов по группам и не вычисляется из агрегатной функции. Он возвращает каждую запись из исходной таблицы. И дает вам примечание в журнале, «этот шаг требует повторного слияния» или что-то в этом роде. Иногда это моющее средство полезно. Но я знаю истинных экспертов SQL, которым не понравилась эта функция, и избегал ее, как чумы. Многие базы данных будут вызывать ошибку из такой инструкции SELECT. – Quentin

+0

Ух, вы имеете в виду, что это не единственное, что делает SAS SQl? Argh !!!!!! Что происходит с этими языками, которые делают неправильную вещь вместо того, чтобы возвращать ошибку? В любом случае, решение = выяснить, что делать с этими 4 столбцами, которые вы исключаете из набора образцов, предоставленных вами. – Twelfth

ответ

7

Реализованный мой комментарий выше - это скорее ответ.

В SAS SQL в запросе с предложением group by, включающем посторонние столбцы в предложении select (то есть столбцы, не являющиеся частью группы, а не производные от агрегирующей функции), SAS «удаляет» сводную статистику назад к исходным данным (с заметкой на этот счет). Большинство SQL-запросов просто выкидывают ошибку. Ниже приведен пример:

data have; 
    input gender $ age score; 
    cards; 
M 10 100 
M 20 200 
F 30 300 
F 40 400 
; 
run; 

proc sql; 
    select gender, mean(age) as AvgAge, SCore 
    from have 
    group by gender 
    ; 
quit; 

возвращается:

gender  AvgAge  score 
F    35  300 
F    35  400 
M    15  100 
M    15  200 

В ваш код, экспозиция, co_itd, MM_NINEQTR_LOSS и MM_LIFE_LOSS все посторонние колонны, в результате чего SAS в пересобрать.

Когда remerging встречается, вы увидите следующее сообщение в журнале SAS:

ПРИМЕЧАНИЕ: Запрос требует remerging резюме статистика с оригинальным данных.

См remerging данные раздела SAS documentation on summary-function для получения более подробной информации

+5

Чтобы запретить поведение повторной записи, используйте параметр NOREMERGE proc sql или параметр системы NOSQLREMERGE. – vasja