Сравнение Informix SQL count()
Вопрос
Я пытаюсь создать SQL-запрос, который будет подсчитывать как общее количество строк для каждого идентификатора, так и количество оценок «FN%» и «W%», сгруппированных по идентификатору.Если эти числа равны, то у учащегося есть либо все «FN%», либо все «W%», либо комбинация того и другого.
Мне нужен список всех идентификаторов, у которых есть статистика только «FN%» или «W%».
пример идентификатора # 683 и 657 войдет в набор результатов запроса, а 603, 781 и 694 — нет.
id stat
683 WF
683 WF
683 WF
683 WF
683 W
683 W
657 W
657 W
657 W
657 W
781 B+
781 IP
781 WP
781 WP
603 FN
603 FN
603 F
603 FN
603 FN
694 B
694 B+
694 CI
694 LAB
694 WF
694 WF
пример вывода:
683
657
Решение
Вот два возможных решения, которые я могу придумать.Я не уверен, будут ли они работать в Informix:
SELECT id
FROM foo a
GROUP BY id
HAVING COUNT(*) = (
SELECT COUNT(*)
FROM foo b
WHERE a.id = b.id
AND (b.stat LIKE 'FN%' OR b.stat LIKE 'W%')
);
И если подзапросы в HAVING
предложение запрещено, возможно, вместо этого сработает следующее:
SELECT id
FROM (
SELECT id, COUNT(*) stat_count
FROM foo
WHERE (stat LIKE 'FN%' OR stat LIKE 'W%')
GROUP BY id
) a
WHERE stat_count = (SELECT COUNT(*) FROM foo b WHERE a.id = b.id);
Обновлять:Я только что попробовал это в Oracle, и оба работают.
Другие советы
От этого объяснения у меня болит голова.Вы ищете объединение этих двух комплектов?
- идентификаторы, статистика которых соответствует только "W%"
- идентификаторы, статистика которых соответствует только «FN%»
В этом случае сделайте запрос UNION с подзапросом для каждого из наборов.
Где xxxx — временная таблица, содержащая эту информацию для обработки.....
select id, fullname, count(id) ttl
from xxxx
group by id, fullname
into temp www with no log;
select id, fullname, count(id) ttl_f
from xxxx
where grd like 'FN%' or grd like 'W%'
group by id, fullname
into temp wwww with no log;
select www.id, www.fullname
from www, wwww
where www.id = wwww.id and www.ttl = wwww.ttl_f;
Это было написано против исходного вопроса:
select first 50
c.id,
(select trim(fullname) from entity where id = c.id) fullname,
count(*),
(select count(*) from courses where id = c.id and grd like 'FN%') FN,
(select count(*) from courses where id = c.id and grd like 'W%') W
from courses c
group by 1
По какой-то причине подзапрос для получения имени выполняется намного быстрее, чем использование соединения.
Редактировать:Следующее будет иметь то же поведение, что и ответ yukondude, но будет работать лучше на нашем компьютере HPUX/Informix v10.00.HC5.
select c.id
from courses c
where not exists (
select id
from courses
where (grd not like 'W%' and grd not like 'FN%')
and id = c.id
)
group by 1