重新选择选择中的值

时间:2015-01-08 16:19:05

标签: sql oracle select

我必须重新制作这个选择,它只能写成一个没有任何子选择的选择。我不知道如何解决它。

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;    

1 个答案:

答案 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”看起来很奇怪;如果它真的是一个数字字段,则那些不应该在引号中。