2010-07-01 5 views
2

Je travaille dans MySQL et j'ai un peu de mal à construire une requête qui résumera les colonnes de deux tables. Je veux comparer la quantité de demandes par jour, pour une table contenant des enregistrements horaires et une table contenant l'agrégation quotidienne, par jour. Idéalement, la somme de chacun serait identique.Comment joindre correctement des tables et utiliser un groupe pour résumer des données dans MySQL?

Voici le schéma:

Tableau horaire:

CREATE TABLE requests_hourly (
customer_id INT, 
date DATETIME, 
requests BIGINT, 
req_type SMALLINT); 

Tableau quotidien

CREATE TABLE requests_daily (
customer_id INT, 
date DATE, 
requests BIGINT, 
req_type SMALLINT); 

ne fonctionne pas SQL pour me toutes les demandes, par req_type sur les deux tables pour Juin 2010

SELECT 
SUM(h.requests), 
SUM(d.requests), 
h.req_type 
FROM requests_hourly h 
LEFT OUTER JOIN requests_daily d ON d.req_type = h.req_type 
WHERE h.date >= '2010-06-01 00:00:00' 
AND h.date < '2010-07-01 00:00:00' 
AND d.date >= '2010-06-01 00:00:00' 
AND d.date < '2010-07-01 00:00:00' 
GROUP BY h.req_type; 

J'ai le sentiment que l'erreur est dans le JOIN. Merci d'avance pour votre aide!

Réponse

je lui ai donné du crédit à Pierre pour la réponse, mais il a besoin d'un peu de modification. Voici donc le code MySQL SQL:

SELECT * 
FROM 
    (SELECT SUM(requests) AS 'Daily Request Sum', req_type 
    FROM requests_daily 
    WHERE date BETWEEN '2010-06-01 00:00:00' AND '2010-07-01 00:00:00' 
    GROUP BY req_type, date) d 
    INNER JOIN 
    (SELECT SUM(requests) AS 'Hourly Request Sum', req_type 
    FROM requests_hourly 
    WHERE date BETWEEN '2010-06-01 00:00:00' AND '2010-07-01 00:00:00' 
    GROUP BY req_type, DATE(date)) h 
USING (req_type, date) 
+0

Je suis sûr que vous devez sélectionner le champ "date" dans les deux instructions SELECT internes, sinon INNER JOIN ne pourra pas se joindre au champ "date". Et vous voudrez alors changer le premier "SELECT *" à; SELECT date, req_type, 'Somme de la demande horaire', 'Somme de la demande quotidienne' J'espère que tout a du sens ... –

Répondre

0

Selon mon analyseur de requête c'est la méthode la plus rapide/plus efficace présenté jusqu'ici:

SELECT * 
FROM 
    (SELECT SUM(requests) AS 'Daily Request Sum', req_type 
    FROM requests_daily 
    WHERE date BETWEEN '2010-06-01 00:00:00' AND '2010-07-01 00:00:00' 
    GROUP BY req_type) 
    INNER JOIN 
    (SELECT SUM(requests) AS 'Hourly Request Sum', req_type 
    FROM requests_hourly 
    WHERE date BETWEEN '2010-06-01 00:00:00' AND '2010-07-01 00:00:00' 
    GROUP BY req_type) 
USING (req_type, date) 

Il jachères logique simple en limitant la taille et prearranging les index dans les tables jointes avant l'opération prend place réduit de manière significative le surdéclaré relativement "cher" encouru en faisant correspondre les index des deux tables (req_type) entre eux d'autant plus que vous n'avez pas d'index uniques (req_type) qui forcera la base de données à effectuer des recherches plutôt que des recherches.

J'espère que cela vous a été utile.

+0

J'ai essayé cette approche, ça ne marche pas ... J'ai d'abord eu une erreur disant que chaque table nécessitait un alias, puis les données étaient étranges car toutes les données des 2èmes sujets SELECT étaient Enfin, après avoir ajouté la date à l'USING (req_type, date) cela a fonctionné.J'apprécie votre aide.Je vais vous remercier de la réponse –

+0

Je suis désolé je pensais avec un état d'esprit Oracle 10g pas MySQL –

+0

Tout va bien ici.Si cela ne vous dérange pas, ajoutez les corrections au bas de votre réponse afin que les autres ne soient pas confus/induits en erreur. Merci encore! –

0

J'utiliserais une sous-requête.

SELECT `req_type` 
    , `date` 
    , COUNT(0) AS `daily_data_count` 
    , (
      SELECT COUNT(0) 
      FROM `requests_hourly` 
      WHERE CAST(`date` AS DATE) 
       = `requests_daily`.`date` 
     ) AS `hourly_data_count` 
    FROM `requests_daily` 
WHERE `date` BETWEEN '2010-06-01' AND '2010-06-30' 
GROUP BY `req_type`, `date` 
0

Avez-vous envisagé aborder le problème avec une union tous.

select 
    sum(requests) total, 
    req_type 
from 
    requests_daily 
where 
requests_daily.date >= '2010-06-01 00:00:00' AND requests_daily.date < '2010-07-01 00:00:00' 
group by requests_daily.req_type 
union all 
select 
    sum(requests) total, 
    req_type 
from 
    requests_hourly 
where 
requests_hourly.date >= '2010-06-01 00:00:00' AND requests_hourly.date < '2010-07-01 00:00:00' 
group by requests_hourly.req_type 

Profitez-en!

+0

J'ai, mais ne correspond pas à l'exigence. L'UNION fournit deux lignes pour chaque date + req_type. :-(J'en ai besoin dans une rangée Merci –

Questions connexes