2015-06-17 75 views
0

我希望有人能夠幫助我。我有一些相當冗長的SQL代碼,它可以提取幾位信息,包括銷售和網絡數據。我需要運行這個多個城市。但是,不要多次重新運行代碼,每次都要手動更改城市。我想知道是否可以使用宏,以便代碼只寫入一次,但城市是某種宏變量,當代碼運行時,它會讀取下來說一個感興趣的城市表,輸出將是一個表爲每一個。多個變量和宏

將事情放入上下文中,下面是代碼的摘錄,您可以在該示例中看到變量「City」,即「London」。

rsubmit; 
proc sql; 
    create table help as 
     select distinct a.customer_id, max(a.level) as level, a.london 
      from (
       select distinct customer_id, max(SESSION_DT) as session_dt format date9., TXT, 
        case when TXT in ('Gold') then 1 
         when TXT in ('Silver') then 2 
         when TXT in ('Bronze') then 3 
         else 4 end as level, 
        case when customer_id is not null then "3" else '' end as London 
         from search_data 
          where CITY in ('London') and TXT is not null 
           group by 1) a 
group by 1; 
quit; 
endrsubmit; 

回答

2

你肯定可以把城市名稱的字符串成宏變量,然後解析出來,但是,它將配備的64K字節長度的限制,以及宏編程的複雜性。下面是我在這種情況下要做的事情: 1.將主代碼放入宏 2.將所有城市名稱放入SAS表中。 3.使用CALL EXECUTE()動態調用宏。

%macro test(city=London); 
rsubmit; 
proc sql; 
    create table help as 
     select distinct a.customer_id, max(a.level) as level, a.london 
      from (
       select distinct customer_id, max(SESSION_DT) as session_dt format date9., TXT, 
        case when TXT in ('Gold') then 1 
         when TXT in ('Silver') then 2 
         when TXT in ('Bronze') then 3 
         else 4 end as level, 
        case when customer_id is not null then "3" else '' end as London 
         from search_data 
          where CITY eq "&city." and TXT is not null 
           group by 1) a 
group by 1; 
quit; 
endrsubmit; 
%mend; 

data _null_; 
set cities; /*this is where you store city names in a variable named CITY, one per row*/ 
call execute ('%test (city= '||city ||')'); 
run; 
+0

謝謝你,那是幫助。真的很感激它。 – Holly14

1

如果我正確地理解你的代碼,你可以完成你在一個SQL一步想要的東西,而不是通過城市試圖循環使用宏:

proc format; 
    value $level. 
     'Gold' = 1 
     'Silver' = 2 
     'Bronze' = 3 
     other = 4 
     ; 

     value customer_city 
       . = '' 
      other = 3 
      ; 

run; 

proc sql; 
    create table help as 
    select 
     distinct customer_id 
    , city 
    , max(session_id) as session_id 
    , max(put(TXT, $level.)) as level 
    , put(customer_id, customer_city.) as customer_city 
    from search_data 
    where TXT is not null 
    group by customer_id, city 
    ; 
quit; 

這裏的「customer_city」將採取的地方你有什麼作爲「a.London」,「a.Tokyo」等

沒有你的「search_data」的描述和你想要的輸出的例子,我不能有信心地說這個代碼將完全做你的想要 - 它現在甚至可能會有一些錯誤。但是你應該能夠適當地修改它,並且一步完成所有的總結。

在您的方法中,SQL通過search_data循環一次,然後再循環聚合數據。那麼你必須爲你擁有的每一個不同的城市做到這一點。換句話說,您將掃描數據集的次數約爲2 *城市數量。如果search_data很大,這將比在一個SQL步驟中做得慢很多。

如果你真的需要一個單獨的表中的每個城市,那麼你可以用這個宏將它們分割:

%macro subset_city(data, city); 

    data &city._table(rename=(customer_city=&city.)); 
     set &data.; 

     where city = &city.; 
    run; 

%mend subset_city; 

data _null_; 
    set list_of_cities; 

    call execute ('%subset_cities(data =help, city= '||city ||')'); 
run; 
+0

謝謝。這有助於我的理解。對此,我真的非常感激。 – Holly14