2016-03-30 4 views
1

Je dois générer un rapport qui me donnera la somme des nombres des tables A, B et C pour les événements qui ont été stockée à l'aide Hive et mes seaux S3 ont été séparés par Organization_idComment optimiser ma requête ruche pour trouver la somme du nombre d'enregistrements de plusieurs tables

pour exemple: Tableau a - a un record pour chaque jour John (et d'autres employés) va travailler Tableau B - a un record pour chaque appel que John (et autres employés) fait ou prend au travail Tableau C - A un enregistrement pour chaque dépense que John (et autres employés) soumet au travail

Fondamentalement, je veux une somme des comptes de A, B et C pour John (employee_id) au cours du dernier mois. Il devrait y avoir seulement un enregistrement pour chaque date s'il y a un enregistrement dans l'une des 3 tables A, B ou C (et additionner les comptes s'il y a un enregistrement pour une date dans un ou plusieurs des tableaux). Donc, ma sortie est:

Employee id 
Employee Name 
Date 
Count 
123 
John 
02-Jan-2016 
55 
123 
John 
12-Jan-2016 
88 
123 
John 
19-Jan-2016 
103 

La requête que je suis venu avec est:

select adcts.employee_name, adcts.employee_id,Total_count as event_count, adcts.event_date 
from 
     (select coalesce(Evts.employee_id,imps.employee_id,AEvts.employee_id) as employee_id 
     , coalesce(Evts.employee_name,imps.employee_name,AEvts.employee_name) as employee_name 
     , coalesce(Evts.Event_count,0) + coalesce(Imps.Impression_count,0) + coalesce (AEvts.Event_Count,0)as Total_Count 
     , coalesce (Evts.event_date,imps.impression_date, AEvts.event_date) as event_date 
    from 
     (select employee_id, employee_name, count(*) as Event_count,event_date 
     from mm_events 
     where organization_id = 100048 
     and event_date between '2016-02-01' and '2016-02-04' 
     group by employee_id, employee_name,event_date) Evts 
     full outer join 
     (select employee_id, employee_name, count(*) as Impression_count, impression_date 
     from mm_impressions 
     where organization_id = 100048 
     and impression_date between '2016-02-01' and '2016-02-04' 
     group by employee_id, employee_name,impression_date) Imps 
     on Evts.employee_id = Imps.employee_id 
     full outer join 
     (select employee_id, employee_name, count(*) as Event_count,event_date 
     from mm_attributed_events 
     where organization_id = 100048 
     and event_date between '2016-02-01' and '2016-02-04' 
     and event_type = 'click' 
     group by employee_id, employee_name,event_date) AEvts 
    on AEvts.employee_id=Evts.employee_id 
     ) adcts  
join 
     (select distinct c.employee_id from default.t1_meta_dmp c 
     where c.employee_dmp_enabled='inherits' 
     and c.agency_dmp_enabled = 'inherits' 
     and c.agency_status='true' 
     and c.employee_status='true' 
     and c.organization_id = 100048) cc 
on adcts.employee_id=cc.employee_id 
order by adcts.employee_id asc 

J'ai 2 questions:

1. Dois-je la bonne requête? 2. Comme j'utilise 'full outer join', je reçois plus d'une entrée pour la même date. Quelqu'un peut-il suggérer un meilleur moyen d'atteindre le résultat? Autre requête peut-être

Répondre

0

Vous obtenez plus d'une entrée pour le même date parce que vous regroupez par date dans les sous-requêtes, mais les rejoindre que par employee_id. C'est pourquoi vos enregistrements sont dupliqués après la jointure. Vous devez également ajouter event_date à la condition de jointure. Il semble que vous n'avez pas du tout besoin de FULL JOIN. Rejoindre est plus cher que union all. Utilisez UNION ALL sélectionner de chaque table puis group by employee_name, employee_id, event_date et le nombre total():

select employee_id, employee_name, sum(Event_count) as Total_Count , event_date 
    from 
    (
    select employee_id, employee_name, count(*) as Event_count, event_date from mm_events 
    where organization_id = 100048 and event_date between '2016-02-01' and '2016-02-04' 
group by employee_id, employee_name, event_date 

    union all 
    select employee_id, employee_name, count(*) as Event_count, impression_date as event_date 
    from mm_impressions 
    where organization_id = 100048 and impression_date between '2016-02-01' and '2016-02-04' 
group by employee_id, employee_name,impression_date 

    union all 
    select employee_id, employee_name, count(*) as Event_count,event_date 
    from mm_attributed_events 
    where organization_id = 100048 and event_date between '2016-02-01' and '2016-02-04' and event_type = 'click' 
group by employee_id, employee_name, event_date 
    ) adcts 
    group by employee_id, employee_name, event_date 

Ajoutez votre requête se joindre à cc à la requête ci-dessus.

Toutes les sous-requêtes dans UNION ALL fonctionneront en parallèle