2017-04-24 75 views
0

我與PROC SQL在SAS的工作和我的PROC SQL查詢之一的行爲非常奇怪:別名和組通過SAS PROC SQL語句

我有一個大的數據集(約1萬行),其看起來是這樣的:

apple_key profit price cost months date  
golden_d  0.03  12  4  3   01/12 
golden_d  0.03  8  0  2   01/12 
granny_s  0.05  15  5  5   02/12 
red_d  0.04  13  0  1   01/12 
golden_d  0.02  1  2  12   03/14 

在我運行下面的查詢這組數據:

%let picking_date = 01/12; /* I simplify here - this part of my code definitely works */ 

proc sql; 
    CREATE TABLE output AS 
    SELECT 
     (CASE apple_key 
       WHEN "golden_d" THEN 1 
       WHEN "granny_s" THEN 2 
       WHEN "red_d" THEN 3 
     END) AS apple_id, 
     apple_key AS apple_name, 
     (CASE WHEN cost= 0 THEN 0 
      ELSE 1 
     END) AS cost_flag, 
     (CASE 
      WHEN CEIL(months/2) < 5 THEN CEIL(months/2) 
      ELSE 5 
     END) AS age, 
     "McDonalds" as farm, 
     sum(profit*price)/sum(price) as price_weighted_profit 
    FROM input_table 
    WHERE date = "&picking_date."d 
     AND price > cost 
     AND cost >= 0 
     AND cost >= 0 
    GROUP BY apple_id, apple_name, cost_flag, age, farm 
    ; 
run; 

當我運行此我GROUP BY聲明不起作用。我爲單個組獲得了一堆條目 (其中apple_id,apple_name,cost_flag,年齡和農場都是相同的,但是我的聚合不起作用)。

但是,當我分別運行GROUP BY(如下所示)時,一切正常。我爲每個組獲得一個具有「價格加權利潤」的條目:

proc sql; 
    CREATE TABLE output_tmp AS 
    SELECT 
     (CASE apple_key 
       WHEN "golden_d" THEN 1 
       WHEN "granny_s" THEN 2 
       WHEN "red_d" THEN 3 
     END) AS apple_id, 
     apple_key AS apple_name, 
     (CASE WHEN cost= 0 THEN 0 
      ELSE 1 
     END) AS cost_flag, 
     (CASE 
      WHEN CEIL(months/2) < 5 THEN CEIL(months/2) 
      ELSE 5 
     END) AS age, 
     "McDonalds" as farm 
    FROM input_table 
    WHERE date = "&picking_date."d 
     AND price > cost 
     AND cost >= 0 
     AND cost >= 0 
    ; 

    CREATE TABLE output AS 
    SELECT 
     apple_id, 
     apple_name, 
     cost_flag, 
     age, 
     farm, 
     sum(profit*price)/sum(price) as price_weighted_profit 
    FROM output_tmp 
    GROUP BY apple_id, apple_name, cost_flag, age, farm 
    ; 
quit; 

爲什麼會發生這種情況?我該如何解決它?這是讓我有點瘋狂......謝謝前面的幫助

+0

你想通過做一組來計算計數或總和? – Teja

+0

對不起。忘記將摘要函數語句移至第二個「create table」語句。現在應該是正確的。我在這裏試圖計算「price_weighted_profit」 – MRR

+0

您希望從樣本輸入中得到什麼結果?你得到什麼輸出? – Tom

回答

1

它不起作用,因爲group by沒有把總和(利潤*價格)/總和(價格)語句作爲聚合函數。它沒有做到這一點,因爲像年齡的別名,cost_flag等

反正下面是正確的查詢: -

Proc sql; 
    CREATE TABLE output AS 
    SELECT 
      apple_id, 
      apple_name, 
      cost_flag, 
      age, 
      farm, 
      sum(profit*price)/sum(price) as price_weighted_profit 
     FROM 
     (
     SELECT 
      (CASE apple_key 
        WHEN "golden_d" THEN 1 
        WHEN "granny_s" THEN 2 
        WHEN "red_d" THEN 3 
      END) AS apple_id, 
      apple_key AS apple_name, 
      (CASE WHEN cost= 0 THEN 0 
       ELSE 1 
      END) AS cost_flag, 
      (CASE 
       WHEN CEIL(months/2) < 5 THEN CEIL(months/2) 
       ELSE 5 
      END) AS age, 
      "McDonalds" as farm 
     FROM input_table 
     WHERE date = "&picking_date."d 
      AND price > cost 
      AND cost >= 0 
      AND cost >= 0 

     ) a 
     GROUP BY apple_id, apple_name, cost_flag, age, farm; 
     quit; 

讓我知道如果您有任何疑問

+0

非常感謝。這個解決了一切。只是爲了確保我明白了:每次使用'AS'語句都會得到'alias'這些別名正在阻止GROUP BY'語句正確分組。你能幫我理解爲什麼會發生這種情況嗎?如:爲什麼它不識別我的別名? – MRR

+1

是。你的理解是正確的。這是一個錯誤,或者我不知道SAS是如何工作的。得到它的生活 –

+0

聽起來不錯。非常感謝你的幫助! – MRR

0

經驗法則: - 每當您在select子句中使用任何聚合函數,其餘列應該是group by的一部分。在您發佈的問題中,您發佈的申請是總和(利潤*價格)/總和(價格),但是沒有導致問題的組。

Proc sql; 
    CREATE TABLE output AS 
     SELECT 
      (CASE apple_key 
        WHEN "golden_d" THEN 1 
        WHEN "granny_s" THEN 2 
        WHEN "red_d" THEN 3 
      END) AS apple_id, 
      apple_key AS apple_name, 
      (CASE WHEN cost= 0 THEN 0 
       ELSE 1 
      END) AS cost_flag, 
      (CASE 
       WHEN CEIL(months/2) < 5 THEN CEIL(months/2) 
       ELSE 5 
      END) AS age, 
      "McDonalds" as farm, 
      sum(profit*price)/sum(price) as price_weighted_profit 
     FROM input_table 
     WHERE date = "&picking_date."d 
      AND price > cost 
      AND cost >= 0 
      AND cost >= 0  
     GROUP BY apple_id, apple_name, cost_flag, age, farm; 
     quit; 
+0

嗨。感謝您的幫助,但如上所述,我在上述兩個版本中都使用了「GROUP BY」。其中一人似乎沒有工作就是沒有工作。或者,也許我誤解了你?你可以再詳細一點嗎? – MRR

+0

你能用上面我寫的sql創建表嗎? – Teja

0

我懷疑發生了什麼是remerging。 SAS PROC SQL接受這樣的代碼:

proc sql; 
    select a.*, count(*) 
    from a; 

這並不彙總數據。相反,它將整個計數放在每一行上。換句話說,如果select中的密鑰與group by不完全匹配,則根據group by密鑰計算聚合函數,但結果會放在單獨的行上。其他數據庫使用窗口函數的子集來完成此操作。

在你的情況下,淹沒並不明顯。我認爲存在關鍵的困惑,因爲您在select中使用與原始數據中相同的名稱。我的建議是更改別名,使其明確無誤,並確保group by中的密鑰是明確的。