Informix SQL count() comparaciones
Pregunta
Estoy tratando de construir una consulta SQL que se tomarán en cuenta tanto el número total de filas para cada id, y el número de 'FN%' y 'W%' grados agrupados por id.Si los números son iguales, entonces el estudiante sólo tiene todos los 'FN%' o todos 'W%' o una combinación de ambos.
Necesito una lista de todos los id que sólo tienen estadísticas de 'FN%' o 'W%'
ejemplo id # 683 & 657 haría en el conjunto de resultados de la consulta, pero 603, 781 & 694 no
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
ejemplo de salida:
683
657
Solución
Aquí hay dos soluciones posibles que se me ocurre. No estoy seguro de si funcionarán en 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%')
);
Y si subconsultas en la cláusula HAVING
son verboten, tal vez esto va a funcionar en su lugar:
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);
Actualización:. Acabo de intentar esto en Oracle, y tanto el trabajo
Otros consejos
Esta explicación hace que me duela la cabeza. ¿Está buscando la unión de estos dos conjuntos?
- ids que sólo tienen estadísticas que coinciden con "W%"
- ids que sólo tienen estadísticas que coinciden con "FN%"
Si ese es el caso, lo convierten en una consulta de unión con una sub-consulta para cada uno de los conjuntos.
donde XXXX es la tabla temporal que mantiene esta información para ser procesada .....
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;
Esto fue escrito en contra de la pregunta original:
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
La subconsulta para recuperar el nombre es mucho más rápido que usar una unión por alguna razón.
Editar: A continuación tendrá el mismo comportamiento que la respuesta de yukondude pero se comporta mejor en nuestra caja de HP-UX / 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