我必须重新制作这个选择,它只能写成一个没有任何子选择的选择。我不知道如何解决它。
select e.exam_name, e.percentage, cc.cert_name, c.company_name, cert_type_name, cert_level_name, version_number,cert_version_name, count(*) as pocet,
MIN(ppp.points) as minPoints,
MAX(ppp.points) as maxPoints,
(
((select count(*) from registration reg where pass = '1')*100)/
(select count(*) from registration ppp)
) as prctU,
(select count(*) from registration ppp where ppp.exam_id = e.exam_id and pass='0') as numFail
from person p
join registration ppp using (id_cert_person)
join provide_exam pe using(id_cert_company)
join company c using(id_cert_company)
join exam e on (e.exam_id=pe.exam_id)
join required_exam re on (re.exam_id=e.exam_id)
join certificate cc using(cert_id)
join cert_type cet using(id_cert_type)
left join address addr on (c.id_address = addr.id_address)
left join cert_level cl using(id_cert_level)
left join version_db vd on(vd.id_version_db =cc.id_version_db )
group by exam_name,percentage, cert_name, company_name, cert_type_name, cert_level_name, version_number,cert_version_name;
答案 0 :(得分:1)
正如现在所写,子查询需要在group by
中重复,因为虽然它们在内部包含聚合函数,但它们本身并不是主选择列表中的聚合。因此你的错误。
我不确定联接的选择性如何,但作为一个起点,你可以做类似的事情:
select e.exam_name, e.percentage, cc.cert_name, c.company_name, cert_type_name,
cert_level_name, version_number,cert_version_name,
count(*) as pocet,
MIN(ppp.points) as minPoints,
MAX(ppp.points) as maxPoints,
100 * count(case when pass = '1' then ppp.some_field end)
/ count(ppp.some_field) as prctU,
count(case when pass = '0' then ppp.some_field) as numFail
from person p
...
count()
函数忽略空值; case
内部意味着只计算相关行。
这可以避免再次查询相同的表,特别是因为子查询没有正确地与主查询相关联。但是,如果不知道模式和键,这可能会多次计算相同的值,因此您可能需要在count函数调用中使用键字段和可能的distinct关键字。显然使用真正的列,而不是some_field
。
将通过/失败标志作为字符但设置为“0”或“1”看起来很奇怪;如果它真的是一个数字字段,则那些不应该在引号中。