0
votes

Oracle SQL Sum avec conditions

Je tente de résumer (heures actuelles), (heures de maladie) par le ministère et le mois. Cette somme doit inclure le département qu'ils travaillent dans lesquels j'ai fait en incluant une déclaration de cas. J'y ai essayé moi-même plusieurs fois cependant, je ne peux pas sembler l'avoir à travailler comme prévu. XXX PRE>

code d'exemple pour les données brutes, etc.: P>

Expected Results:
Department    HoursSick     HoursPresent     Month
Trolley P6      0             21              01
Trolley P6     21             0               02 
Trolley P3     14             12.5            02


4 commentaires

Vous voulez somme (cas lorsque alors horaires_sworked) Pour chaque colonne, vous vous attendez à générer la somme de, plus un groupe sur les autres colonnes sélectionnées, probablement.


P.s. J'espère que vous avez une table contenant les départements et que vous utilisez cela pour rejoindre votre table pour obtenir le nom du département de l'ID de département?


Sur un Sidenote: Ne comparez jamais les dates avec des chaînes ( Compte_Date> '01 / déc / 2017 '). Le SGBD essaiera de convertir la chaîne en une date qui réussira ou échouera (avec une exception ou une date incorrecte) en fonction des paramètres de session. Utilisez ANSI DATE LITHTES PLUS: Compte_Date> Date '2017-12-01' .


@Boneist merci pour la résolution. J'aurais accepté votre réponse cependant, ce n'était qu'un commentaire. Nous avons une table qui a des départements Toutefois, les données d'ici sont trop granulaires, le destinataire du rapport voulait que plusieurs codes ont été fusionnés dans un «parc de trolley».


3 Réponses :


3
votes

Vous avez besoin d'agrégation conditionnelle, pour éviter de répéter les expressions les nichez dans une table dérivée ( Vue en ligne em> dans oracle parler):

select
    Department
  ,sum(case when Wage_type = 'SICK' then Hours_worked else 0 end) as HoursSick
  ,sum(case when Wage_type = 'Normal' then Hours_worked else 0 end) as HoursPresent
  ,"Month_Number"
  ,"Year"
from
 (
    Select 
     (case 
        when TPDRS.ORG_CODE = 1010 then  'Trolley P1'
        when TPDRS.ORG_CODE = 1011 then  'Trolley P2'
        when TPDRS.ORG_CODE = 1053 then  'Trolley P3'
        when TPDRS.ORG_CODE between 1054 and 1057 then  'Trolley P4'
        when TPDRS.ORG_CODE between 1040 and 1047 then  'Trolley P5'
        when TPDRS.ORG_CODE in ('1063','1064','1065','1068') then 'Trolley P6'
        else 'NOT REQUIRED'
            end) as Department
    ,EXTRACT(Month from TPDRS.ACCOUNT_DATE) "Month_Number"
    ,EXTRACT(Year from TPDRS.ACCOUNT_DATE) "Year"

    from TrolleyParkAttendant  TPDRS
    WHERE TPDRS.ACCOUNT_DATE > '01/DEC/2017'
     AND (TPDRS.WAGE_GRP_DB IN ( 'O', 'N' ) or WAGE_CODE = 'SICK')
 ) dt
group by
    Department
  ,"Month_Number"
  ,"Year"


1 commentaires

Merci. J'ai suivi le commentaire de Boneist ci-dessus comme référence cependant, votre réponse était la même.



2
votes

Vous pouvez utiliser l'instruction SQL suivante avec Agrégation conditionnelle CODE>

SELECT decode(1063,'Trolley P6',1054,'Trolley P3') as Department,
       sum(case when Wage_type='SICK' then Hours_worked end) as HoursSick,
       sum(case when Wage_type='Normal' then Hours_worked end) as HoursPresent,
       to_char(TPDRS.ACCOUNT_DATE,'mm') as "Month"       
  FROM TrolleyParkAttendant  TPDRS
 WHERE TPDRS.ACCOUNT_DATE > '01/DEC/2017'
   AND (TPDRS.WAGE_GRP_DB IN ( 'O', 'N' ) or WAGE_CODE = 'SICK')
 GROUP BY decode(1063,'Trolley P6',1054,'Trolley P3'), 
          to_char(TPDRS.ACCOUNT_DATE,'mm');


2 commentaires

Vous êtes manquant fin pour les expressions de cas . Et vous ne pouvez pas grouper par un nom d'alias défini dans la clause SELECT ( département ici).


@Thorstenkettner Exactement, l'erreur que je ne fais pas normalement, merci.



2
votes

Votre modèle de données semble manquer à la fois d'une table de département et d'une table d'organisation. Vous devriez probablement les créer. Eh bien, CTES ( avec code> clause) fera pour l'instant ...

with dept as
(
  select 'P1' as id, 'Trolley P1' as name from dual union all
  select 'P2' as id, 'Trolley P2' as name from dual union all
  select 'P3' as id, 'Trolley P3' as name from dual union all
  select 'P4' as id, 'Trolley P4' as name from dual union all
  select 'P4' as id, 'Trolley P5' as name from dual union all
  select 'P6' as id, 'Trolley P6' as name from dual
)
, org as
(
  select 1010 as code, 'P1' as dept_id from dual union all
  select 1011 as code, 'P2' as dept_id from dual union all
  select 1053 as code, 'P3' as dept_id from dual union all
  select 1054 as code, 'P4' as dept_id from dual union all
  select 1057 as code, 'P4' as dept_id from dual union all
  select 1040 as code, 'P5' as dept_id from dual union all
  select 1047 as code, 'P5' as dept_id from dual union all
  select 1063 as code, 'P6' as dept_id from dual union all
  select 1064 as code, 'P6' as dept_id from dual union all
  select 1065 as code, 'P6' as dept_id from dual union all
  select 1068 as code, 'P6' as dept_id from dual
)
select
  dept.name as department,
  sum(case when tpa.wage_code = 'SICK' then wage_hours end) as hours_sick,
  sum(case when tpa.wage_grp_db in ('O', 'N') then wage_hours end) as hours_present,
  to_char(account_date, 'yyyy-mm') as month
from trolleyparkattendant tpa
join org on org.code = tpa.org_code
join dept on dept.id = org.dept_id
group by dept.name, to_char(account_date, 'yyyy-mm') 
order by month, department;


1 commentaires

Thorsten, oui, je pourrais l'utiliser comme je soupçonne que cela pourrait changer à l'avenir et au lieu de mettre à jour le PLSQL, je pourrais mettre à jour les données de la table. Merci pour les informations +1