我正在尝试编写一个查询,告诉我Female
每种颜色的数量。
White - 2
Blue - 5
Green - 13
到目前为止,我有以下查询,我的一些尝试被注释掉了:
SELECT a.id AS aid, af.field_name AS aname, afv.field_value
FROM applications app, applicants a, application_fields af, application_fields_values afv, templates t, template_fields tf
WHERE a.application_id = app.id
AND af.application_id = app.id
AND afv.applicant_id = a.id
AND afv.application_field_id = af.id
#AND af.template_id = t.id
AND af.template_field_id = tf.id
AND t.id = tf.template_id
AND afv.created_at >= '2013-01-01'
AND afv.created_at <= '2013-12-31'
#AND af.field_name = 'Male'
AND afv.field_value = 1
ORDER BY aid, aname
#GROUP BY aid, aNAME
#HAVING aname = 'Female';
目前此查询返回如下数据:
aid | aname | field_value
4 Female 1
4 White 1
5 Green 1
5 Female 1
6 Female 1
6 White 1
7 Blue 1
7 Female 1
8 Female 1
8 Blue 1
9 Male 1
9 Green 1
表格结构:
applications:
id
application_fields:
id
application_id
field_name
applications_fields_values:
id
application_field_id
applicant_id
field_value
template:
id
template_fields:
id
template_id
applicant:
id
application_id
示例数据:
application_fields
id | application_id | field_name |template_id | template_field_id
1 | 1 | blue | 1 | 1
2 | 1 | green | 1 | 2
3 | 1 | female | 1 | 3
application_fields_values
id | application_field_id | applicant_id | field_value
4 | 1 | 1 | 1
5 | 2 | 1 | 0
6 | 3 | 1 | 1
templates
id | name |
1 | mytemplate |
template_fields
id | template_id | field_name |
1 | 1 | blue
2 | 1 | green
3 | 1 | female
修改
我非常确定下面的查询能够获得我正在寻找的内容,但它的速度非常慢,我的最大表格行数不到30K。
查询
SELECT af.field_name AS aname, sum(afv.field_value) AS totals
FROM applications app, applicants a, application_fields af, application_fields_values afv, templates t, template_fields tf
WHERE a.application_id = app.id
AND af.application_id = app.id
AND afv.applicant_id = a.id
AND afv.application_field_id = af.id
AND af.template_field_id = tf.id
AND t.id = tf.template_id
AND afv.created_at >= '2013-01-01'
AND afv.created_at <= '2013-12-31'
AND afv.field_value = 1
AND a.id IN (
SELECT
a2.id
FROM applications app2, applicants a2, application_fields af2, application_fields_values afv2, templates t2, template_fields tf2
WHERE af2.application_id = app2.id
AND afv2.applicant_id = a2.id
AND afv2.application_field_id = af2.id
AND af2.template_field_id = tf2.id
AND t2.id = tf2.template_id
AND afv2.created_at >= '2013-01-01'
AND afv2.created_at <= '2013-12-31'
#AND af2.field_name = 'Male'
AND af2.field_name = 'Female'
AND afv2.field_value = 1
)
GROUP BY aname;
产生结果:
aname | totals
Green 2
Black 27
Blue 5
答案 0 :(得分:4)
SELECT f1.field_name, count(*) as total
FROM application_fields f1
JOIN applications_fields_values v1
ON v1.application_field_id = f1.id
JOIN applications_fields_values v2
ON v1.applicant_id = v2.applicant_id
JOIN applications_fields f2
ON v2.application_field_id = f2.id
WHERE v1.field_value = 1
AND v2.field_value = 1
AND f2.field_name = 'Female'
AND f1.field_name != 'Female'
AND f1.created_at BETWEEN '2013-01-01' AND '2013-12-31'
GROUP BY f1.field_name
除非您有其他要求,否则您似乎无需引用表格templates
,template_fields
,applications
或applicant
来解决您的问题。此外,您还不清楚如何识别哪种application_fields
代表颜色。如果您有更多相关信息,可能会添加一些条件。
答案 1 :(得分:0)
查询看起来很好,只需在WHERE
子句中添加条件,如果您希望过滤掉基于分组的结果,则应在HAVING
内添加
试试这个
SELECT
af.field_name AS aname,
count(afv.field_value) as totals
FROM
applications app,
applicants a,
application_fields af,
application_fields_values afv,
templates t,
template_fields tf
WHERE
a.application_id = app.id
AND af.application_id = app.id
AND afv.applicant_id = a.id
AND afv.application_field_id = af.id
#AND af.template_id = t.id
AND af.template_field_id = tf.id
AND t.id = tf.template_id
AND afv.created_at >= '2013-01-01'
AND afv.created_at <= '2013-12-31'
#AND af.field_name = 'Male'
AND afv.field_value = 1
AND aname = 'Female'
ORDER BY
aname
GROUP BY
aNAME
答案 2 :(得分:0)
尝试使用EXISTS函数代替IN
SELECT af.field_name AS aname, sum(afv.field_value) AS totals
FROM applications app, applicants a, application_fields af, application_fields_values afv, templates t, template_fields tf
WHERE a.application_id = app.id
AND af.application_id = app.id
AND afv.applicant_id = a.id
AND afv.application_field_id = af.id
AND af.template_field_id = tf.id
AND t.id = tf.template_id
AND afv.created_at >= '2013-01-01'
AND afv.created_at <= '2013-12-31'
AND afv.field_value = 1
AND EXISTS (
SELECT
1
FROM applications app2, applicants a2, application_fields af2, application_fields_values afv2, templates t2, template_fields tf2
WHERE af2.application_id = app2.id
AND afv2.applicant_id = a2.id
AND afv2.application_field_id = af2.id
AND af2.template_field_id = tf2.id
AND t2.id = tf2.template_id
AND afv2.created_at >= '2013-01-01'
AND afv2.created_at <= '2013-12-31'
#AND af2.field_name = 'Male'
AND af2.field_name = 'Female'
AND afv2.field_value = 1
AND a.id = a2.id -- add this condition
)
GROUP BY aname;
来源:http://dev.mysql.com/doc/refman/5.5/en/optimizing-subqueries.html
注意:根据几个条件,这个修改可能会更快或更慢,如果它在该(源)页面的底部考虑几个条件则会更慢。
答案 3 :(得分:0)
您应该考虑更清晰的设计。似乎有不同的问题。
例如,通过使用template和template_fields值(以及提供的示例数据),我可以猜测[应用程序字段]派生自[templates],只要应用程序只有一个模板。在这种情况下,您可以通过multi_ to-multi表设计application_fields_values,如下所示:
applications:
id | template_id
application_fields_values:
application_id | template_field_id | field_value
application fields: redundant
template information derived from template_fields
这适用于[应用程序字段]应该存在与否(即如果部分遵循模板字段集), 或者如果一组模板是强制性的。
通常,您的表似乎有多余的引用。