同时分组和累积记录

时间:2011-03-09 19:22:42

标签: mysql sql

我正在编写一个针对数据库中高级多对多表的查询。我把它称为高级表,因为它是一个多对多的表和额外的字段。该表在fields表和students表之间映射数据。字段表包含学生可以使用的潜在字段,有点像联系系统(即姓名,学校,地址等)。我需要查询的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 个答案:

答案 0 :(得分:2)

所以为了制作一个看起来像这样的表,我会假设像

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

会是你想要的。我们不能只对“响应”进行分组,因为如果你有一个学生回答洛杉矶的城市,另一个学生回应洛杉矶州(路易斯安那州),他们会补充。此外,如果同一个城市处于不同的州,我们需要首先通过加入学生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