2012-03-15 63 views
0

我是SQL新手,經歷了多次嘗試和錯誤以及搜索書籍和因特網。我不得不重複查詢五年中每月數據的總和,我想在表中插入每月的結果作爲列。我試圖每月添加新的列將查詢中的聚合值插入到SQL中的表中

alter table add column, insert etc. 

但我不能說得對。下面是我用簡碼和feb07:它工作正常

CREATE TABLE "TVD_db"."lebendetiere" 
(nuar text, 
ak text, 
sex text, 
jan07 text, 
feb07 text, 
märz07 text, 
april07 text, 
mai07 text, 
juni07 text, 
juli07 text, 
aug07 text, 
sept07 text, 
okt07 text, 
nov07 text, 
dez07 text, 
jan08 text, 
.... 
dez11 text); 


INSERT INTO "TVD_db"."lebendetiere" (nuar, ak, sex, jan07) 
SELECT 
"AUFENTHALTE"."nuar", 
CASE WHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") < 365 THEN '1' WHEN DATE('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") > 730 THEN 3 ELSE 2 END AS AK, 
CASE WHEN "AUFENTHALTE"."isweiblich" = 'T' THEN 'female' ELSE 'male' END AS sex, 
COUNT("AUFENTHALTE"."tierid") 
FROM "TVD_db"."AUFENTHALTE" 
WHERE DATE("AUFENTHALTE"."gueltigvon") <= DATE('2007-01-01') 
AND DATE("AUFENTHALTE"."gueltigbis") >= DATE('2007-01-01') 
GROUP BY "AUFENTHALTE"."nuar", 
CASE WHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") < 365 THEN '1' WHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") > 730 THEN 3 ELSE 2 END, 
CASE WHEN "AUFENTHALTE"."isweiblich" = 'T' THEN 'female' ELSE 'male' END 
ORDER BY "AUFENTHALTE"."nuar", 
CASE WHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") < 365 THEN '1' wWHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") > 730 THEN 3 ELSE 2 END, 
CASE WHEN "AUFENTHALTE"."isweiblich" = 'T' THEN 'female' ELSE 'male' END 
; 

--until這裏

UPDATE "TVD_db"."lebendetiere" SET "feb07"= --this is the part I cant get right... 
(SELECT 
COUNT("AUFENTHALTE"."tierid") 
FROM "TVD_db"."AUFENTHALTE" 
WHERE DATE("AUFENTHALTE"."gueltigvon") <= DATE('2007-02-01') 
AND DATE("AUFENTHALTE"."gueltigbis") >= DATE('2007-02-01') 
GROUP BY "AUFENTHALTE"."nuar", 
CASE WHEN DATE ('2007-02-01')- DATE ("AUFENTHALTE"."gebdat") < 365 THEN '1' WHEN DATE ('2007-02-01')- DATE ("AUFENTHALTE"."gebdat") > 730 THEN 3 ELSE 2 END, 
CASE WHEN "AUFENTHALTE"."isweiblich" = 'T' THEN 'female' ELSE 'male' END 
ORDER BY "AUFENTHALTE"."nuar", 
CASE WHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") < 365 THEN '1' wWHEN DATE ('2007-01-01')- DATE ("AUFENTHALTE"."gebdat") > 730 THEN 3 ELSE 2 END, 
CASE WHEN "AUFENTHALTE"."isweiblich" = 'T' THEN 'female' ELSE 'male' END); 

有沒有人溶液或做我必須做一個表,每個月,然後加入結果如何?

+0

是否有某些原因,你需要月結果列?這樣做會更簡單,查詢每月生成一行,並按年/月的日期提取分組。 – dbenhur 2012-03-15 20:11:59

回答

2

完全閱讀您的文章後,這裏是一個完整重新設計應該對SQL/PostgreSQL領域的初學者有一些洞察力。

  • 我建議不要混合使用identifiers in PostgreSQL。只使用小寫字母,那麼您不必重複引用它們,並且您的代碼更易於閱讀。你也避免了很多可能的混淆。

  • 使用table aliases使您的代碼更具可讀性。

  • INSERT的SELECT語句中的列名是不相關的。這就是爲什麼我評論出來(避免可能的命名衝突)。

  • 使用GROUP BY和ORDER BY中的序號進一步簡化。

  • 請勿爲每個新月使用單獨的列。使用標識月份的列並每月添加一行。
    如果您確實需要每月有一列的設計,那麼您需要一個大的CASE語句或一個數據透視查詢。請參閱tablefunc擴展。但對於一個SQL新手來說,這是一件複雜的事情。我真的覺得,你想每個月都有一排。

  • 我用generate_series()至2007年1月和12月2011.

  • 之間每月產生一個排,我改變了設計,你不需要額外的更新。這全部在一個INSERT中完成。

我簡化了很多其他的東西。這是我會建議,而不是:

CREATE TABLE tvd_db.lebendetiere(
    nuar text, 
,alterskat integer 
,sex text 
,datum date 
,anzahl integer 
); 

INSERT INTO tvd_db.lebendetiere (nuar, alterskat, sex, datum, anzahl) 
SELECT a.nuar 
     ,CASE WHEN a.gebdat >= '2006-01-01'::date THEN 1 -- use >= ! 
      WHEN a.gebdat < '2005-01-01'::date THEN 3 
      ELSE          2 END -- AS alterskat 
     ,CASE WHEN a.isweiblich = 'T' THEN 'female' ELSE 'male' END -- AS sex 
     ,m.m 
     ,count(*) -- AS anzahl 
FROM tvd_db.aufenthalte a 
CROSS JOIN (
    SELECT generate_series('2007-01-01'::date 
          ,'2011-12-01'::date, interval '1 month')::date 
    ) m(m) 
WHERE a.gueltigvon <= m.m 
AND a.gueltigbis >= m.m 
GROUP BY a.nuar, 2, 3, m.m 
ORDER BY a.nuar, 2, 3, m.m;