Ayuda con unas consultas SQL >_<

Buenos días.

Tengo que hacer una práctica en la que diseñe e implemente una base de datos para una compañía telefónica, con MySQL. Tengo, entre otras, las siguientes tablas:

CREATE TABLE Ticket (
idTicket integer(11) AUTO_INCREMENT,
NTelefono integer(9),
NDestino integer(9),
Tipo char(1),
Cantidad integer,
Fecha timestamp,
PRIMARY KEY (idTicket),
FOREIGN KEY (NTelefono) REFERENCES Linea(Ntelefono)
);

CREATE TABLE Factura (
NTelefono integer(9),
FechaFacturacion date,
ImporteTotal float(4,4),
PRIMARY KEY (NTelefono, FechaFacturacion),
FOREIGN KEY (NTelefono) REFERENCES Linea(NTelefono)
);

Pues bien, entre otras consultas, quería hacer una que fuera ver en qué hora concreta hay más actividad global, que vienen a ser los tickets (un ticket es cada acción tarificable realizada por una línea, bien sea llamar, enviar un mensaje o navegar). He hecho la siguiente consulta, y funciona, pero es redundante, por lo que os pido ayuda a ver si me la podéis arreglar >_<.

SELECT Hora FROM (SELECT COUNT(*) AS Actividad,HOUR(Fecha) AS Hora FROM Ticket GROUP BY Hora) T WHERE Actividad=(SELECT MAX(Actividad) FROM (SELECT COUNT(*) AS Actividad,HOUR(Fecha) AS Hora FROM Ticket GROUP BY Hora) T2 ) ;

También quería hacer otra consulta que me devolviera el mes con el consumo más alto (tomando los datos, de nuevo, de todos los años). Tengo la siguiente consulta, pero no sé cómo hacer para que sólo me devuelva Mes sin volver a anidar otro SELECT:

SELECT MAX(Consumo),Mes FROM (SELECT SUM(ImporteTotal) AS Consumo,MONTH(FechaFacturacion) AS Mes FROM Factura GROUP BY Mes) T;

Si se os ocurre alguna otra consulta que pueda ser interesante, la recibiré con los brazos abiertos :) . ¡Muchas gracias!
(mensaje borrado)
Taurus5 escribió:Buenos días.

Tengo que hacer una práctica en la que diseñe e implemente una base de datos para una compañía telefónica, con MySQL. Tengo, entre otras, las siguientes tablas:

CREATE TABLE Ticket (
idTicket integer(11) AUTO_INCREMENT,
NTelefono integer(9),
NDestino integer(9),
Tipo char(1),
Cantidad integer,
Fecha timestamp,
PRIMARY KEY (idTicket),
FOREIGN KEY (NTelefono) REFERENCES Linea(Ntelefono)
);

CREATE TABLE Factura (
NTelefono integer(9),
FechaFacturacion date,
ImporteTotal float(4,4),
PRIMARY KEY (NTelefono, FechaFacturacion),
FOREIGN KEY (NTelefono) REFERENCES Linea(NTelefono)
);

Pues bien, entre otras consultas, quería hacer una que fuera ver en qué hora concreta hay más actividad global, que vienen a ser los tickets (un ticket es cada acción tarificable realizada por una línea, bien sea llamar, enviar un mensaje o navegar). He hecho la siguiente consulta, y funciona, pero es redundante, por lo que os pido ayuda a ver si me la podéis arreglar >_<.

SELECT Hora FROM (SELECT COUNT(*) AS Actividad,HOUR(Fecha) AS Hora FROM Ticket GROUP BY Hora) T WHERE Actividad=(SELECT MAX(Actividad) FROM (SELECT COUNT(*) AS Actividad,HOUR(Fecha) AS Hora FROM Ticket GROUP BY Hora) T2 ) ;

También quería hacer otra consulta que me devolviera el mes con el consumo más alto (tomando los datos, de nuevo, de todos los años). Tengo la siguiente consulta, pero no sé cómo hacer para que sólo me devuelva Mes sin volver a anidar otro SELECT:

SELECT MAX(Consumo),Mes FROM (SELECT SUM(ImporteTotal) AS Consumo,MONTH(FechaFacturacion) AS Mes FROM Factura GROUP BY Mes) T;

Si se os ocurre alguna otra consulta que pueda ser interesante, la recibiré con los brazos abiertos :) . ¡Muchas gracias!

A lo rápido y desde el móvil:
Si no quieres hacer tanta subconsulta puedes usar having, en estas te dejará una consulta más clara.

En la primera con "redundante" te refieres a que salen horas repetidas (usa distinct si es el caso) o a que estas haciendo algo muy similar 2 veces (usa having)?
Gracias por responder :).

Con redundante me refería a que hago dos veces la misma subconsulta, que con muchos registros puede ser realmente pesada, por lo que hacerla dos veces podría ser un problema (obviamente no para los datos que voy a manejar yo, pero sí los que podría tener teóricamente). Miraré a ver cómo puedo usar HAVING.
Pueds probar como te ha dicho usando Having y quizás a lo mejor te ahorraría trabajo utilizar un un ORDER BY con un ROWNUM, TOP, LIMIT... el que uses, vamos.
Yo creo que haciendo algo así tendría que salirte y es bastante mas simple (es en plsql, pero vamos, en sql debe ser parecido)

SELECT
        EXTRACT(HOUR FROM FECHA) AS HORA,
        COUNT(1) AS "Nº TICKETS"
FROM
        TICKET
GROUP BY EXTRACT(HOUR FROM FECHA)
ORDER BY "Nº TICKETS" DESC


y para lo de los meses diría que es lo mismo pero extrayendo el mes


SELECT MES, MAX(TICKETS)
FROM (
SELECT
        EXTRACT(MONTH FROM FECHA) AS MES,
        COUNT(1) AS TICKETS"
FROM
        TICKET
GROUP BY EXTRACT(MONTH FROM FECHA)
)


A ver si te sirve que no lo he probado.
6 respuestas