2014-02-18 67 views
0

我正在使用Postgres 9.1來嘗試獲取一些數據。
我有三個(虛擬/消毒)表:使用具有多個條件的計數的查詢

Table "public.students" 
    Column |   Type    | Modifiers 
--------------+-----------------------------+----------- 
id   | uuid      | not null 
name   | character varying   | 
birth_date | date      | 
last_exam_at | timestamp without time zone | 
created_at | timestamp without time zone | 
code   | character varying   | 
gender  | character varying   | 
Indexes: 
    "students_id_key" UNIQUE CONSTRAINT, btree (id) 
Referenced by: 
    TABLE "exams" CONSTRAINT "exams_student_id_fkey" 
        FOREIGN KEY (student_id) REFERENCES students(id) 

Table "public.exams_essays" 
    Column | Type | Modifiers 
----------+------+----------- 
exam_id | uuid | 
essay_id | uuid | 

Table "public.exams" 
     Column  |   Type    | Modifiers 
-------------------+-----------------------------+----------- 
id    | uuid      | not null 
student_id  | uuid      | 
created_at  | timestamp without time zone | 
completed_at  | timestamp without time zone | 
course   | character varying   | 

Table "public.essays" 
    Column  |   Type    | Modifiers 
-----------------+-----------------------------+----------- 
id    | uuid      | not null 
essay_type  | character varying   | not null 
filename  | character varying   | 

而且我想獲得以下信息,通過created_at::datestudent_id分組:

  • 考試
  • 號總數歷史散文(exam.course = 'history'
  • 英文散文數(exam.course = 'english'

這些查詢中的每一個都不是很難單獨完成,但將它們放在一起證明是困難的。

回答

1
SELECT created_at::date, student_id 
     ,count(*) AS exams 
     ,sum(CASE WHEN course = 'history' THEN essays ELSE 0 END) AS essays_hist 
     ,sum(CASE WHEN course = 'english' THEN essays ELSE 0 END) AS essays_engl 
FROM public.exams x 
LEFT JOIN (
    SELECT exam_id AS id, count(*) AS essays 
    FROM public.exams_essays 
    GROUP BY exam_id 
    ) s USING (id) 
GROUP BY created_at::date, student_id; 

我彙總正表在連接前,從而避免行開始的乘法。使查詢更簡單(IMO)並更快。

+0

@David:你知道'GROUP BY 1'也是有效的語法,對吧? [例如。](http://stackoverflow.com/questions/3800551/select-first-row-in-each-group-by-group/7630564#7630564) –

+0

是的,我(現在)意識到這一點,但我不得不查看它,並且我發現查詢更清晰,更容易擺弄,並且更清楚地說明了一切。 –

1
SELECT COUNT(DISTINCT EX.exam_id) TotalExams, 
     SUM(CASE WHEN E.course = 'history' THEN 1 ELSE 0 END) HistoryEssays, 
     SUM(CASE WHEN E.course = 'english' THEN 1 ELSE 0 END) EnglishEssays 
FROM public.exams AS EX 
LEFT JOIN public.exams_essays AS EE 
    ON EX.exam_id = EE.essay_id 
+0

雖然我需要論文數量,但可能與考試次數不同,因爲一次考試可能有許多論文。 –

+1

@ DavidN.Welton哦,好吧,沒有意識到。現在更新我的答案。 – Lamak