Ir al contenido


Foto

Como hacer una instruccion SQL que se basa en otras sql


  • Por favor identifícate para responder
21 respuestas en este tema

#1 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 06 septiembre 2010 - 08:34

Hola a todos
Pues sucede que estoy migrando una BD de Access para MySQL, y me encontre con una dificultad que no se como solucionarla
Tal vez la solucion que use en access no fue la mas indicada, pero me resolvia el problema
El problema es que tengo una tabla donde en un campo se selecciona el tipo de PC (De Escritorio, Servidor o Portatil), y en un informe se hace un resumen donde se cuentan la cantidad de cada uno de ellos
La solucion que di en access fue:
- Crear una consulta filtrando por Servidores, otra basada en esa para totalizar la cantidad
- (y lo mismo para los otros tipos)
- Y otra consulta basada en esas 3, mas otros datos de la tabla para hacer el Informe

Pero cuando lo voy a hacer en MySQL, eso de las consultas anidadas me dejo "en blanco"

Es posible que lo que haya hecho es una "chapuza", pero agradeciaria que me indicaran como hacerlo en MySQL, o si no, una forma mejor de hacer lo que quiero



  • 0

#2 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 septiembre 2010 - 08:41

Podrías poner las consultas que tenías en access, para tener mas claridad?
  • 0

#3 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 06 septiembre 2010 - 08:41

Saludos.

Nos serviría si puedes publicar ambas sentencias para ver las diferencias, entiendo que si utilizas ANSI SQL no tendrás problemas para realizar el traspaso entre motores.

P.D. Wilson me gano...
  • 0

#4 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.304 mensajes
  • LocationMéxico

Escrito 06 septiembre 2010 - 08:43

Por lo que veo haces varias consultas, pero.... porque no hacer un solo query con los datos que necesitas

Algo así



sql
  1. SELECT tabla1.servidor, tabla2.totalizar, tabla3.otrostipos, tabla4.otrosdatos FROM tabla1
  2. LEFT JOIN tabla2 ON tabla2.campo = tabla1.campo
  3. LEFT JOIN tabla3 ON tabla3.campo = tabla1.campo
  4. LEFT JOIN tabla4 ON tabla4.campo = tabla1.campo AND
  5.                         tabla4.campo = tabla2.campo AND
  6.                         tabla4.campo = tabla3.campo
  7. ORDER BY loquequieras



Salud OS

PD, Coincido con Wilson y con Rolphy, para no estar escribiendo al aire ;)

  • 0

#5 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 06 septiembre 2010 - 09:04

En Access solo se usaban dos tipos de PC, pero la filosofia es la misma

1ra Consulta: Para servidores Profesionales



sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="Profesional"));



2da Consulta para Totalizarlos:


sql
  1. SELECT [cc _ServidoresProf].IDCENTRO, COUNT([cc _ServidoresProf].Servidor) AS CuentaDeServidor
  2. FROM [cc _ServidoresProf]
  3. GROUP BY [cc _ServidoresProf].IDCENTRO;



3ra Consulta para PC servidores


sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="PC Server"));



4ta Consulta para totalizarlos:


sql
  1. SELECT [cc _ServidoresPC].IDCENTRO, COUNT([cc _ServidoresPC].Servidor) AS CuentaDeServidor
  2. FROM [cc _ServidoresPC]
  3. GROUP BY [cc _ServidoresPC].IDCENTRO;



Y la 5ta que lo resume todo:


sql
  1. SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor AS CantServPC, cc_CantServProf.CuentaDeServidor AS CantServProf
  2. FROM Entidades INNER JOIN ((Centros LEFT JOIN cc_CantServPC ON Centros.IdCentros = cc_CantServPC.IDCENTRO)
  3. INNER JOIN cc_CantServProf ON Centros.IdCentros = cc_CantServProf.IDCENTRO) ON Entidades.CodEnt = Centros.CODENT
  4. GROUP BY Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor, cc_CantServProf.CuentaDeServidor;



Como ven parece un poco "enredado" al menos para mi  :
  • 0

#6 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 06 septiembre 2010 - 09:11

Las tablas relacionadas (1 ---> Muchos) usadas en las consultas son:

Entidades  --->  Centros  --->  Computadoras
  • 0

#7 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 septiembre 2010 - 09:25

Mirando a groso modo con una sola consulta bastaría, y programar  las agrupaciones con sus cantidades en el reporte.

saludos
  • 0

#8 Wilson

Wilson

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.137 mensajes

Escrito 06 septiembre 2010 - 09:37

Algo así



sql
  1. SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro,Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM .......
  3. INNER JOIN.....



A propósito ¿que herramienta estás usando para crear el reporte?
  • 0

#9 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 06 septiembre 2010 - 09:49

Ejemplo:



sql
  1. SELECT E.CodEnt, E.NombreEntidad, C.IdCentros, C.NombreCentro,Co.IDCENTRO, Co.Servidor
  2. FROM Entidades E
  3. LEFT JOIN Centros C WHERE C.IdCentros = E.IdCentros
  4. LEFT JOIN Computadoras Co WHERE Co.IDCENTRO = E.IdCentros

.

OJO es un ejemplo de como deberías hacerlo, lo demás deberás adaptarlo.

Saludos.

  • 0

#10 poliburro

poliburro

    Advanced Member

  • Moderadores
  • PipPipPip
  • 4.945 mensajes
  • LocationMéxico

Escrito 06 septiembre 2010 - 10:29

A

En Access solo se usaban dos tipos de PC, pero la filosofia es la misma

1ra Consulta: Para servidores Profesionales



sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="Profesional"));



2da Consulta para Totalizarlos:


sql
  1. SELECT [cc _ServidoresProf].IDCENTRO, COUNT([cc _ServidoresProf].Servidor) AS CuentaDeServidor
  2. FROM [cc _ServidoresProf]
  3. GROUP BY [cc _ServidoresProf].IDCENTRO;



3ra Consulta para PC servidores


sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="PC Server"));



4ta Consulta para totalizarlos:


sql
  1. SELECT [cc _ServidoresPC].IDCENTRO, COUNT([cc _ServidoresPC].Servidor) AS CuentaDeServidor
  2. FROM [cc _ServidoresPC]
  3. GROUP BY [cc _ServidoresPC].IDCENTRO;



Y la 5ta que lo resume todo:


sql
  1. SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor AS CantServPC, cc_CantServProf.CuentaDeServidor AS CantServProf
  2. FROM Entidades INNER JOIN ((Centros LEFT JOIN cc_CantServPC ON Centros.IdCentros = cc_CantServPC.IDCENTRO)
  3. INNER JOIN cc_CantServProf ON Centros.IdCentros = cc_CantServProf.IDCENTRO) ON Entidades.CodEnt = Centros.CODENT
  4. GROUP BY Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor, cc_CantServProf.CuentaDeServidor;



Como ven parece un poco "enredado" al menos para mi  :


Amigo joanca, si gustas, dime que datos deseas mostrar en la 5ta consulta y te armo la equivalencia para mysql,

  • 0

#11 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 06 septiembre 2010 - 11:55

Wilson: Para el reporte uso QReport

enecumene: Esa parte que tengo que "adaptar" es la que no sé  :|

Poliburro:
Los datos que deseo mostrar es la cantidad de Servidores por tipo (Profesional y PC Server), pero es que el tipo se guarda en un solo campo, es decir, en la tabla computadoras hay un campo que almacena un string, en el cual el usuario selecciona desde un cuadro combinado el tipo correspondiente.

El informe me debe salir así mas o menos:

                                            Cant. Servidores
Centro          Total de PC    Profesional    PC Server
-----------------------------------------------------
Centro 1            30                2                  2
Centro 2            25                1                  1
 
  • 0

#12 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 06 septiembre 2010 - 12:24

Pues intentalo con el mismo ejemplo que te puse, te debería dar lo que esperas.

Saludos.
  • 0

#13 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 06 septiembre 2010 - 12:32

Pues intentalo con el mismo ejemplo que te puse, te debería dar lo que esperas.

Saludos.


Pues lo del ejemplo solo me sirve para agrupar los centros con sus entidades, en eso no hay problemas, el problema radica en contar cada valor del campo Servidores (Profesional y PC Server)
  • 0

#14 enecumene

enecumene

    Webmaster

  • Administrador
  • 7.409 mensajes
  • LocationRepública Dominicana

Escrito 06 septiembre 2010 - 12:34

Pues sólo agregas la clausula COUNT() a la consulta y listo
  • 0

#15 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 07 septiembre 2010 - 12:52

Pues sólo agregas la clausula COUNT() a la consulta y listo


A ver si nos entendemos
Con un COUNT() en la consulta me cuenta los registros (totales o filtrados) del campo que seleccione
Pero en mi caso es que el registro toma 2 valores, y necesito contar los dos valores en un mismo informe

Por ejemplo:
Tienes una tabla Personas con los campos:
Nombre
Apellidos
Sexo
Pais

En un reporte quiero mostrar la cantidad de hombres y la cantidad de mujeres que viven en cada Pais

Pais  Hombres    Mujeres
X          10          10
Y            5            7

Como ves ni Hombres ni Mujeres son campos de la tabla, en la tabla el campo es Sexo que puede tomar como valores [Masculino o Femenino]

Tengo que contar 2 veces el mismo campo, una vez filtrado por M y otra vez filtrado por F, pero para que me salga en un solo informe

  • 0

#16 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.304 mensajes
  • LocationMéxico

Escrito 07 septiembre 2010 - 01:00

Pais  Hombres    Mujeres
X          10          10
Y            5            7


Pues utiliza subconsultas, algo así:



sql
  1. SELECT A.Pais, (SELECT COUNT(sexo) FROM tabla B WHERE B.sexo = 'H' AND B.Pais = A.Pais) AS Hombres,
  2.               (SELECT COUNT(sexo) FROM tabla B WHERE B.sexo = 'M' AND B.Pais = A.Pais) AS Mujeres FROM tabla A



Salud OS
  • 0

#17 poliburro

poliburro

    Advanced Member

  • Moderadores
  • PipPipPip
  • 4.945 mensajes
  • LocationMéxico

Escrito 07 septiembre 2010 - 01:05

La consulta equivalente que buscas es esta



sql
  1.   SELECT Centros.IdCentro, Sumario.Servidor, Sumario.NumProf,
  2.         Sumario.NumServer, SumSerProf, SumSerPc
  3.     FROM Centros AS Centros
  4.   LEFT JOIN (
  5.                 SELECT Computadoras.IDCENTRO, Computadoras.Servidor,
  6.                         SUM(CASE WHEN Computadoras.Servidor= "Profesional" THEN 1 ELSE 0 END) AS NumProf,
  7.                         SUM(CASE WHEN Computadoras.Servidor= "PC Server" THEN 1 ELSE 0 END) AS NumServer,
  8.                   FROM Computadoras
  9.               GROUP BY Computadoras.IDCENTRO, Computadoras.Servidor
  10.               ) AS Sumario
  11.           ON Centros.IdCentro = Sumario.IdCentro
  12.     LEFT JOIN (
  13.                 SELECT IDCENTRO,
  14.                         COUNT(Servidor) AS SumSerProf
  15.                   FROM 'cc _ServidoresProf' AS SerProf
  16.               GROUP BY IDCENTRO;
  17.               ) AS DatSumSerProf
  18.           ON Centros.IdCentro = DatSumSerProf.IdCentro
  19.     LEFT JOIN (
  20.                 SELECT IDCENTRO,
  21.                         COUNT(Servidor) AS SumSerPc
  22.                   FROM 'cc _ServidoresPC' AS SerPc
  23.               GROUP BY IDCENTRO;
  24.               ) AS DatSumSerPc
  25.           ON Centros.IdCentro = DatSumSerPc.IdCentro


  • 0

#18 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 08 septiembre 2010 - 07:49

Poliburro, probe tu sql pero me da error en
[pre][/pre]

sql
  1.   ...  FROM 'cc _ServidoresProf' AS SerProf

[pre]
[/pre]Me parece que es porque en access 'cc _ServidoresProf' es una consulta,
Yo use MySQL Migration TollKit para pasar de access para MySQL, que por supuesto solo pasaron las tablas


  • 0

#19 poliburro

poliburro

    Advanced Member

  • Moderadores
  • PipPipPip
  • 4.945 mensajes
  • LocationMéxico

Escrito 08 septiembre 2010 - 08:53

Poliburro, probe tu sql pero me da error en
[pre][/pre]

sql
  1.   ...  FROM 'cc _ServidoresProf' AS SerProf

[pre]
[/pre]Me parece que es porque en access 'cc _ServidoresProf' es una consulta,
Yo use MySQL Migration TollKit para pasar de access para MySQL, que por supuesto solo pasaron las tablas



je, pues es por eso. Podrias poner la consulta que genera el objeto cc _prof.  Por cierto, es tremendamente problemático incluir espacios en los nombres de tus objetos. Te sugiero amigo que en lo sucesivo los evites.

Saludos.
  • 0

#20 JoAnCa

JoAnCa

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 758 mensajes
  • LocationPinar del Río, Cuba

Escrito 08 septiembre 2010 - 11:29

Tienes razon con eso de los espacios en los nombres de objetos, se me fueron esos (parece que por el copia y pega)  *-)
En realidad para los nombres de las consultas yo uso la nomenclatura c_Nombre ó cc_Nombre

Esta es: cc_ServidoresProf


sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="Profesional"));



Y esta es: cc_ServidoresPC


sql
  1. SELECT Computadoras.IDCENTRO, Computadoras.Servidor
  2. FROM Computadoras
  3. WHERE (((Computadoras.Servidor)="PC Server"));





  • 0