2011-03-09 82 views
0

我正在寫數據庫中的高級多對多表。我把它稱爲高級表,因爲它是一個多對多的表和額外的字段。該表映射字段表和學生表之間的數據。字段表包含學生可以使用的潛在字段,類似於聯繫系統(即姓名,學校,地址等)。我需要查詢的studentvalues表包含字段ID,學生ID和字段答案(即studentid = 1; fieldid = 2; response = Dave Long)。同時分組和累積記錄

所以我的表看起來像這樣:

Table Layout

我需要做的是採取一些傳遞的價值觀和創建分組的累積報告。我想盡可能在​​SQL中做更多的事情。

因此,我擁有的數據將按字段(字段ID),累計字段(字段ID)和我需要按字段分組學生,然後在每個組中計數金額的學生在累積的領域。

所以,比如我有這個數據

ID  STUDENTID  FIELDID  RESPONSE 
1  1    2 *(city)* Wallingford 
2  1    3 *(state)* CT 
3  2    2 *(city)* Wallingford 
4  2    3 *(state)* CT 
5  3    2 *(city)* Berlin 
6  3    3 *(state)* CT 
7  4    2 *(city)* Costa Mesa 
8  4    3 *(state)* CA 

我希望寫一個查詢,我可以生成一個報告,如下所示:

CA - 1 Student 
Costa Mesa   1 

CT - 3 Students 
Berlin    1 
Wallingford   2 

這是可能做到用單個SQL語句還是必須獲取所有組,然後遍歷它們?

編輯這裏是我迄今爲止得到的代碼,但它並沒有提供正確的stateSubtotal(該stateSubtotal是一樣的citySubtotal)

SELECT state, count(state) AS stateSubtotal, city, count(city) AS citySubtotal 
FROM(
    SELECT s1.response AS city, s2.response AS state 
    FROM studentvalues s1 
    INNER JOIN studentvalues s2 
    ON s1.studentid = s2.studentid 
    WHERE s1.fieldid = 5 
    AND s2.fieldid = 6 
) t 
GROUP BY city, state 
+1

你「高級多到多」表通常被稱爲[實體 - 屬性 - 值或EAV模型(http://en.wikipedia.org/wiki/Entity-attribute-value_model )。在你的例子中,實體是'學生',屬性包含在'fields'表中,而值可以在'studentvalues'中找到。 – 2011-03-09 19:28:36

+0

是加利福尼亞州的學生id = 4,或者做一些學生住在兩個地方 – Mikeb 2011-03-09 19:35:36

+0

@Mikeb我寫錯了。所有學生只能有一個領域。 – 2011-03-09 19:55:58

回答

2

因此,爲了使一個表看起來像那樣,我會假設像

State StateSubtotal City   CitySubtotal 
CA  1    Costa Mesa 1 
CT  3    Berlin  1 
CT  3    Wallingford 2 

會是你想要的。我們不能僅僅對Response進行分組,因爲如果你有一個學生回答LA的問題,另一個回答LA的州(路易斯安那州),他們會補充。另外,如果同一個城市處於不同的州,我們需要首先通過加入學生ID來佈置城市和州之間的關聯。

編輯 - 確實,有缺陷的第一種方法。不同的聚合需要不同的分組,因此確實需要每個聚合選擇一個。這給出了正確的結果,但它很醜,我敢打賭它可以改進。如果你在SQL Server上,我會認爲CTE會有幫助,但這不是一種選擇。

select t2.stateAbb, stateSubtotal, t2.city, t2.citySubtotal from 
(
select city, count(city) as citySubTotal, stateAbb from (
select s1.Response as city, s2.Response as StateAbb 
from aaa s1 inner join aaa s2 on s1.studentId = s2.studentId 
where s1.fieldId = 2 and s2.fieldId=3 
) t1 
group by city, stateabb 
) t2 inner join (
select stateAbb, count(stateabb) as stateSubTotal from (
select s1.Response as city, s2.Response as StateAbb 
from aaa s1 inner join aaa s2 on s1.studentId = s2.studentId 
where s1.fieldId = 2 and s2.fieldId=3 
) t3 
group by stateabb 
) t4 on t2.stateabb = t4.stateabb 
+0

這幾乎完美,但它並沒有給我適當的狀態小計。該州的總數似乎是城市的小計。我將我的SQL附加到我的問題。也許我只是寫錯了。 – 2011-03-09 19:53:48

+0

不,你是對的。馬屁精我的部分 – Mikeb 2011-03-09 20:12:04

+0

我現在實際上會忽略每個州的計數。馬虎是可以得到最初的釋放。清理是在我發佈的1.1版本的清單中。 – 2011-03-09 20:22:43