Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 07-11-2023
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Transformado a JOINS
Código SQL [-]
select a.codigo, a.nombre, coalesce(sum(b.votos), 0) votos, coalesce(c.electos, 0) electos, c.circunscripcion,
       d.nombre
from partidos a
join resultados b on b.partido = a.codigo and a.codprv = b.codprv
join poblacion d on a.codprv = d.codprv
left join numelectos c on b.codprv = c.codprv and b.proceso = c.proceso and c.tipo = 'M' and b.partido = c.partido and d.codigo = c.circunscripcion
where
a.codprv = : prvins and
b.proceso = : proceso and
/* Que pasa si no hay ninguna mesa con esa circunscripcion */
b.mesa in (select codigo
           from mesas
           where
           codprv = a.codprv and
           municipio = c.circunscripcion)
group by a.codigo, a.nombre, electos, c.circunscripcion, d.nombre
order by d.nombre, votos desc, electos desc, a.nombre
Responder Con Cita
  #2  
Antiguo 07-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Transformado a JOINS
Gracias por la sugerencia. Tengo que estudiarla porque tal cual me la has planteado he tendio que abortar la ejecución porque llevaba 10 minutos sin sacar nada y tal como he planteado el query yo se ejecutaba en menos de 1 segundo.
Responder Con Cita
  #3  
Antiguo 07-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Transformado a JOINS
Gracias por la idea. He estado probando y si ejecuto el query tal como me propones, como te he dicho antes, se eterniza y tengo que cancelar la ejecución porque llevando 10 minutos no ha sacado nada, y es lógico porque, a mi modesto entender, trataría de sacar todas las filas de la tabla poblacion; y si hago un pequeño cambio:
Código SQL [-]
from partidos a
join resultados b on b.partido = a.codigo and a.codprv = b.codprv
left join numelectos c on b.codprv = c.codprv and b.proceso = c.proceso and c.tipo = 'M' and b.partido = c.partido
join poblacion d on a.codprv = d.codprv and d.codigo = c.circunscripcion
Si no hay datos en NumElectos no saca nada. Seguiré investigando, pero ya mañana.
Responder Con Cita
  #4  
Antiguo 08-11-2023
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Si haces LEFT JOIN con numelectos, también debes hacer LEFT JOIN con las tablas que se unen a ella.
Si numelectos no tiene registros, C.CIRCUNSCRIPCION será nulo y el JOIN con población no devolverá nada.

Código SQL [-]
from partidos a
join resultados b on b.partido = a.codigo and a.codprv = b.codprv
left join numelectos c on b.codprv = c.codprv and b.proceso = c.proceso and c.tipo = 'M' and b.partido = c.partido
*LEFT* join poblacion d on a.codprv = d.codprv and d.codigo = c.circunscripcion

Código SQL [-]
from partidos a
join resultados b on b.partido = a.codigo and a.codprv = b.codprv
left join numelectos c on b.codprv = c.codprv and b.proceso = c.proceso and c.tipo = 'M' and b.partido = c.partido
*LEFT* join poblacion d on a.codprv = d.codprv and d.codigo = c.circunscripcion
*LEFT JOIN* mesas on  codprv = a.codprv and municipio = c.circunscripcion

Para que no se haga eterno deberás tener índices para los campos con los que haces el JOIN.
He visto que tienes PKs, que generan índices para estas tablas, pero que quizás no sean óptimos.

Por ejemplo

Quizás NUMELECTOS debería cambiar el orden de los campos de la PK a CODPRV,PROCESO,TIPO,[PARTIDO <- , -> CIRCUNSCRIPCION],CARGO para que se utilice mejor en el LEFT JOIN.
POBLACION debería tener un índice por CODPRV,CODIGO.
MESAS no tiene ningún índice.
Responder Con Cita
  #5  
Antiguo 08-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Gracias por la orientación.
Responder Con Cita
  #6  
Antiguo 08-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Quizás NUMELECTOS debería cambiar el orden de los campos de la PK a CODPRV,PROCESO,TIPO,[PARTIDO <- , -> CIRCUNSCRIPCION],CARGO para que se utilice mejor en el LEFT JOIN.
POBLACION debería tener un índice por CODPRV,CODIGO.
MESAS no tiene ningún índice.
Perdona por no haber puesto todo.
POBLACION tiene como clave primaria precisamente esa.
MESAS tiene como clave primaria CODPRV, CODIGO. Además tiene otro índice con CODPRV y MUNICIPIO.
Responder Con Cita
  #7  
Antiguo 08-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cita:
Empezado por duilioisola Ver Mensaje
Si haces LEFT JOIN con numelectos, también debes hacer LEFT JOIN con las tablas que se unen a ella.
Si numelectos no tiene registros, C.CIRCUNSCRIPCION será nulo y el JOIN con población no devolverá nada.
Ahora sí. Muchísimas gracias.
Responder Con Cita
  #8  
Antiguo 13-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Pues no sé lo que pasa. El query funciona pero...
Si ejecuto el query como me ha propuesto duilioisola me da este resultado:

No veo de donde sale esa suma de votos que, por otra parte, es el único campo que se calcula mal. Por citar sólo un ejemplo el municipio de Alcázar de San Juan tiene un censo electoral de 23670 personas y los votos emitidos fueron 16192. Sin embargo la suma de votos que hace el query es la que se ve ahí.

Sin embargo si ejectuto este query sólo para ese municipio:
Código SQL [-]
select a.codigo, a.nombre, coalesce(sum(b.votos), 0) votos
from partidos a
join resultados b on b.partido = a.codigo and a.codprv = b.codprv
where
a.codprv = :prvins and a.codigo > 0 and
b.proceso = :proceso and
b.mesa in (select codigo
           from mesas
           where
           codprv = a.codprv and
           municipio = :municipio)
group by a.codigo, a.nombre
order by votos desc, a.nombre
El resultado es este, que es el correcto

No veo por qué se multiplican los datos. He comprobado que si divido las resultados de ambos querys de los partidos que tiene electos en todos los casos sale la misma cifra: 44
Responder Con Cita
  #9  
Antiguo 13-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
He estado probando añadiendo y quitando trozos del query original y descubierto que el problema viene con el último LEFT JOIN:
Código SQL [-]
LEFT JOIN mesas e on  e.codprv = a.codprv and e.municipio = c.circunscripcion
Si se deja, salen mal los datos.
Responder Con Cita
  #10  
Antiguo 13-11-2023
Avatar de Angel.Matilla
Angel.Matilla Angel.Matilla is offline
Miembro
 
Registrado: ene 2007
Posts: 1.350
Poder: 19
Angel.Matilla Va por buen camino
Cada vez estoy más desanimado con este query, y mira que pintaba bien.
Código SQL [-]
select a.codigo, a.nombre, coalesce(sum(b.votos), 0) votos, coalesce(c.electos, 0) electos, c.circunscripcion, d.nombre
from partidos a
left join resultados b on b.partido = a.codigo and a.codprv = b.codprv
left join numelectos c on b.codprv = c.codprv and b.proceso = c.proceso and c.tipo = 'M' and b.partido = c.partido
LEFT join poblacion d on a.codprv = d.codprv and d.codigo = c.circunscripcion
where
a.codprv = rvins and
b.proceso = roceso and
b.mesa in (select codigo
           from mesas
           where
           codprv = a.codprv and
           municipio = c.circunscripcion)
group by a.codigo, a.nombre, electos, c.circunscripcion, d.nombre
order by d.nombre, votos desc, electos desc, a.nombre
He hecho la prueba con left join resultados y con join resultados y eliminando resultados en la tabla NumElectos para que de un municipio no hubiera esos campos pero sí resultados. Y con las tablas completas sale este resultado:

pero si suprimo lo que he comentado sale esto

aunque en la tabla resultados siga habiendo datos del municipio en cuestión (en este caso el 175). No lo entiendo: con LEFT JOIN ¿no deberían salir datos para ese valor? No sé que estoy haciendo mal o no entendiendo.

En el enlcae https://drive.google.com/file/d/1F3V...ew?usp=sharing hay un fichero TABLAS.RAR que tiene el script para crear y llenar las tablas implicadas en el query.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
a vueltas con los servidores de datos anubis Varios 11 13-01-2010 09:37:42
Dando vueltas con las capas CHiCoLiTa Providers 0 24-01-2006 12:09:55
Dandolo vueltas a un indice gario Oracle 0 17-03-2005 14:04:47


La franja horaria es GMT +2. Ahora son las 03:14:04.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi