2011-03-09 77 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