PostgreSQL:不是DISTINCT

时间:2015-09-12 04:44:15

标签: sql postgresql count postgresql-9.3

我正在使用PostgreSQL 9.3,而且我有这个大而丑陋的查询...

SELECT cai.id
FROM common_activityinstance cai
JOIN common_activityinstance_settings cais ON cai.id = cais.activityinstance_id
JOIN common_activitysetting cas ON cas.id = cais.id
WHERE cai.end_time::date = '2015-09-11'
    AND (   key = 'disable_student_nav' AND value = 'True'
         OR key = 'pacing' AND value = 'student');

...这给了我这个结果......

    id  
  ------
   1352
   1352
   1353
   1353
   1354
   1355
 (6 rows)

如何改进查询以获取重复行的计数(本例中为2)?

2 个答案:

答案 0 :(得分:4)

使用子查询

select count(*) total_dups from(
    SELECT count(cai.id)
    FROM common_activityinstance cai
    JOIN common_activityinstance_settings cais ON cai.id = cais.activityinstance_id
    JOIN common_activitysetting cas ON cas.id = cais.id
    WHERE cai.end_time::date = '2015-09-11'
        AND (key = 'disable_student_nav'
                AND value = 'True'
                OR key = 'pacing'
                AND value = 'student')
    group by cai.id having count(cai.id) >1
    ) t

group by cai.id having count(cai.id) > 1可用于查找每个cai.id的重复计数,然后SELECT count(cai.id)(select ...)t可用于查找子查询中所有重复的计数

OR

使用CTE

with cte as (
SELECT count(cai.id)
    FROM common_activityinstance cai
    JOIN common_activityinstance_settings cais ON cai.id = cais.activityinstance_id
    JOIN common_activitysetting cas ON cas.id = cais.id
    WHERE cai.end_time::date = '2015-09-11'
        AND (key = 'disable_student_nav'
                AND value = 'True'
                OR key = 'pacing'
                AND value = 'student')
    group by cai.id having count(cai.id) >1
    )

    select count(*) from  cte

Difference between CTE and SubQuery?

答案 1 :(得分:0)

由于查询的结构,我怀疑重复项可能只来自查询的or部分。如果限制为最多两个重复,则可以在没有子查询的情况下进行计算:

SELECT count(cai.id) - count(distinct cai.id)
FROM common_activityinstance cai JOIN
     common_activityinstance_settings cais
     ON cai.id = cais.activityinstance_id JOIN
     common_activitysetting cas
     ON cas.id = cais.id
WHERE cai.end_time::date = '2015-09-11' AND
      (key, value) IN (('disable_student_nav', 'True'), ('pacing', 'student'));

注意:这仅适用于每个ID只出现一次或两次的特殊情况。