PDA

Ver la Versión Completa : Filtrar resultados en un query


Angel.Matilla
04-11-2023, 11:38:33
Para el mismo mi query de mi pregunta anterior (¿Por qué no usa el índice? (https://www.clubdelphi.com/foros/showthread.php?t=96469))
SELECT DISTINCT A.Codigo, A.Nombre, COALESCE(RDB$GET_CONTEXT('USER_TRANSACTION', 'MUNICIPIO'), 1) Municipio,
RDB$SET_CONTEXT('USER_TRANSACTION', 'MUNICIPIO',
(SELECT DISTINCT COALESCE(Municipio, 1) FROM Mesas WHERE CodPrv = B.CodPrv AND Codigo = B.Mesa))
FROM Partidos A
LEFT JOIN Resultados B ON A.CodPrv = B.CodPrv AND A.Codigo = B.Partido AND B.Proceso = :Proceso
WHERE A.CodPrv = :PrvIns AND A.Codigo > 0
ORDER BY Municipio, A.Nombre
me da, por ejemplo, este resultado:
https://i.ibb.co/StWNDWZ/Query.jpg
El valor de la columna Municipio igual a 1 significa población desconocida; ¿cómo puedo evitar que se muestren esos valores? He probado con esta condición:
AND COALESCE(RDB$GET_CONTEXT('USER_TRANSACTION', 'MUNICIPIO'), 1) > 1
y me devuelve un query vacío. Y si uso
AND Municipio > 1
me dice que la columna Municipio es desconocida.

aposi
04-11-2023, 18:59:31
prueba:



WHERE A.CodPrv = :PrvIns AND A.Codigo > 0
having municipio > 1
ORDER BY Municipio, A.Nombre

duilioisola
05-11-2023, 21:55:29
No entiendo porqué utilizas CONTEXT.
¿No es más fácil utilizar un SUBSELECT?

SELECT DISTINCT A.Codigo, A.Nombre,
/* COALESCE para que si el subselect devuelve nulo (no existe ningún registro con esa condición), muestre un 1. */
/* FIRST 1 para que me devuelva solo un municipio si hubiera más de uno */
/* ORDER BY para que el registro que devuelva sea siempre el primero, en orden de municipio */
COALESCE(
(SELECT FIRST 1 Municipio FROM Mesas
WHERE
CodPrv = B.CodPrv AND
Codigo = B.Mesa
ORDER BY Municipio), 1)
FROM Partidos A
LEFT JOIN Resultados B ON A.CodPrv = B.CodPrv AND A.Codigo = B.Partido AND B.Proceso = :Proceso
WHERE
A.CodPrv = :PrvIns AND
A.Codigo > 0 AND
/* EXISTS indica si existe al menos un registro en la tabla con esa condición */
exists((SELECT Municipio FROM Mesas WHERE CodPrv = B.CodPrv AND Codigo = B.Mesa))
/* Indico el tercer campo para ordenar, que se corresponde con el resultado del subselect */
ORDER BY 3 /*Municipio*/, A.Nombre

Angel.Matilla
06-11-2023, 10:23:17
WHERE A.CodPrv = :PrvIns AND A.Codigo > 0
having municipio > 1
ORDER BY Municipio, A.Nombre

HAVING Sólo funciona si hay un GROUP BY

Angel.Matilla
06-11-2023, 10:43:58
No entiendo porqué utilizas CONTEXT.
¿No es más fácil utilizar un SUBSELECT?
Te contesto aquí a las dos sugerencias que me haces sobre CONTEXT, en este hilo y en el otro. Tienes razón, pero como estoy probando diversas sintaxis del query por eso esta estructura.
Entiendo la idea que me sugieres pero me da este error:
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Token unknown - line 16, column 2.
Exists.
(1,154 sec)
en:
exists ((SELECT Municipio FROM Mesas WHERE CodPrv = B.CodPrv AND Codigo = B.Mesa))
Seguiré probando por este camino que me parece mucho más lógico y sobre todo sencillo que el que estaba usando yo.

Angel.Matilla
06-11-2023, 11:03:47
Vale, ya encontré lo que pasa.
exists ((SELECT Municipio FROM Mesas WHERE CodPrv = B.CodPrv AND Codigo = B.Mesa))
Por lo que sea no tolera los dos paréntesis. Efectivamente es una estructura mucho más lógica y rápida. Muchas gracias por la idea.

Casimiro Notevi
06-11-2023, 11:40:13
Puedes quitar un par de paréntesis.