
Como hacer una instruccion SQL que se basa en otras sql
#1
Escrito 06 septiembre 2010 - 08:34
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
#2
Escrito 06 septiembre 2010 - 08:41
#3
Escrito 06 septiembre 2010 - 08:41
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...
#4
Escrito 06 septiembre 2010 - 08:43
Algo así
SELECT tabla1.servidor, tabla2.totalizar, tabla3.otrostipos, tabla4.otrosdatos FROM tabla1 LEFT JOIN tabla2 ON tabla2.campo = tabla1.campo LEFT JOIN tabla3 ON tabla3.campo = tabla1.campo LEFT JOIN tabla4 ON tabla4.campo = tabla1.campo AND tabla4.campo = tabla2.campo AND tabla4.campo = tabla3.campo ORDER BY loquequieras
Salud OS
PD, Coincido con Wilson y con Rolphy, para no estar escribiendo al aire

#5
Escrito 06 septiembre 2010 - 09:04
1ra Consulta: Para servidores Profesionales
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="Profesional"));
2da Consulta para Totalizarlos:
SELECT [cc _ServidoresProf].IDCENTRO, COUNT([cc _ServidoresProf].Servidor) AS CuentaDeServidor FROM [cc _ServidoresProf] GROUP BY [cc _ServidoresProf].IDCENTRO;
3ra Consulta para PC servidores
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="PC Server"));
4ta Consulta para totalizarlos:
SELECT [cc _ServidoresPC].IDCENTRO, COUNT([cc _ServidoresPC].Servidor) AS CuentaDeServidor FROM [cc _ServidoresPC] GROUP BY [cc _ServidoresPC].IDCENTRO;
Y la 5ta que lo resume todo:
SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor AS CantServPC, cc_CantServProf.CuentaDeServidor AS CantServProf FROM Entidades INNER JOIN ((Centros LEFT JOIN cc_CantServPC ON Centros.IdCentros = cc_CantServPC.IDCENTRO) INNER JOIN cc_CantServProf ON Centros.IdCentros = cc_CantServProf.IDCENTRO) ON Entidades.CodEnt = Centros.CODENT 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

#6
Escrito 06 septiembre 2010 - 09:11
Entidades ---> Centros ---> Computadoras
#7
Escrito 06 septiembre 2010 - 09:25
saludos
#8
Escrito 06 septiembre 2010 - 09:37
SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro,Computadoras.IDCENTRO, Computadoras.Servidor FROM ....... INNER JOIN.....
A propósito ¿que herramienta estás usando para crear el reporte?
#9
Escrito 06 septiembre 2010 - 09:49
SELECT E.CodEnt, E.NombreEntidad, C.IdCentros, C.NombreCentro,Co.IDCENTRO, Co.Servidor FROM Entidades E LEFT JOIN Centros C WHERE C.IdCentros = E.IdCentros 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.
#10
Escrito 06 septiembre 2010 - 10:29
En Access solo se usaban dos tipos de PC, pero la filosofia es la misma
1ra Consulta: Para servidores Profesionales
sql
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="Profesional"));
2da Consulta para Totalizarlos:
sql
SELECT [cc _ServidoresProf].IDCENTRO, COUNT([cc _ServidoresProf].Servidor) AS CuentaDeServidor FROM [cc _ServidoresProf] GROUP BY [cc _ServidoresProf].IDCENTRO;
3ra Consulta para PC servidores
sql
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="PC Server"));
4ta Consulta para totalizarlos:
sql
SELECT [cc _ServidoresPC].IDCENTRO, COUNT([cc _ServidoresPC].Servidor) AS CuentaDeServidor FROM [cc _ServidoresPC] GROUP BY [cc _ServidoresPC].IDCENTRO;
Y la 5ta que lo resume todo:
sql
SELECT Entidades.CodEnt, Entidades.NombreEntidad, Centros.IdCentros, Centros.NombreCentro, cc_CantServPC.CuentaDeServidor AS CantServPC, cc_CantServProf.CuentaDeServidor AS CantServProf FROM Entidades INNER JOIN ((Centros LEFT JOIN cc_CantServPC ON Centros.IdCentros = cc_CantServPC.IDCENTRO) INNER JOIN cc_CantServProf ON Centros.IdCentros = cc_CantServProf.IDCENTRO) ON Entidades.CodEnt = Centros.CODENT 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,
#11
Escrito 06 septiembre 2010 - 11:55
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
#12
Escrito 06 septiembre 2010 - 12:24
Saludos.
#13
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)
#14
Escrito 06 septiembre 2010 - 12:34
#15
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
#16
Escrito 07 septiembre 2010 - 01:00
Pais Hombres Mujeres
X 10 10
Y 5 7
Pues utiliza subconsultas, algo así:
SELECT A.Pais, (SELECT COUNT(sexo) FROM tabla B WHERE B.sexo = 'H' AND B.Pais = A.Pais) AS Hombres, (SELECT COUNT(sexo) FROM tabla B WHERE B.sexo = 'M' AND B.Pais = A.Pais) AS Mujeres FROM tabla A
Salud OS
#17
Escrito 07 septiembre 2010 - 01:05
SELECT Centros.IdCentro, Sumario.Servidor, Sumario.NumProf, Sumario.NumServer, SumSerProf, SumSerPc FROM Centros AS Centros LEFT JOIN ( SELECT Computadoras.IDCENTRO, Computadoras.Servidor, SUM(CASE WHEN Computadoras.Servidor= "Profesional" THEN 1 ELSE 0 END) AS NumProf, SUM(CASE WHEN Computadoras.Servidor= "PC Server" THEN 1 ELSE 0 END) AS NumServer, FROM Computadoras GROUP BY Computadoras.IDCENTRO, Computadoras.Servidor ) AS Sumario ON Centros.IdCentro = Sumario.IdCentro LEFT JOIN ( SELECT IDCENTRO, COUNT(Servidor) AS SumSerProf FROM 'cc _ServidoresProf' AS SerProf GROUP BY IDCENTRO; ) AS DatSumSerProf ON Centros.IdCentro = DatSumSerProf.IdCentro LEFT JOIN ( SELECT IDCENTRO, COUNT(Servidor) AS SumSerPc FROM 'cc _ServidoresPC' AS SerPc GROUP BY IDCENTRO; ) AS DatSumSerPc ON Centros.IdCentro = DatSumSerPc.IdCentro
#18
Escrito 08 septiembre 2010 - 07:49
[pre][/pre]
... 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
#19
Escrito 08 septiembre 2010 - 08:53
Poliburro, probe tu sql pero me da error en
[pre][/pre]sql
... 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.
#20
Escrito 08 septiembre 2010 - 11:29

En realidad para los nombres de las consultas yo uso la nomenclatura c_Nombre ó cc_Nombre
Esta es: cc_ServidoresProf
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="Profesional"));
Y esta es: cc_ServidoresPC
SELECT Computadoras.IDCENTRO, Computadoras.Servidor FROM Computadoras WHERE (((Computadoras.Servidor)="PC Server"));