2009-06-25 13 views
0

J'ai créé le tableau suivant (via UNION ALL):Changer la date et le groupe par mois fiscal Fin

ID  Date   Hour Weight Fiscal 
AAA  1/27/2009  0  10   0 
AAA  1/30/2009  0  20   0 
AAA  2/14/2009  0  10   0 
AAA  2/18/2009  0  20   0 
AAA  2/27/2009  0  20   0 
AAA  2/28/2009  0  20   0 
AAA  1/14/2009  10  0   0 
AAA  2/14/2009  20  0   0 
AAA  2/16/2009  10  0   0 
AAA  2/25/2009  10  0   0 
AAA  2/26/2009  10  0   0 
AAA  3/3/2009   20  0   0 
NULL   0     0  0   1/28/2009 
NULL   0     0  0   2/27/2009 
NULL   0     0  0   3/29/2009 

Et je voudrais récupérer:

ID  Date  Hour Weight 
    AAA  1/28/2009 10 10 
    AAA  2/27/2009 50 50 
    AAA  3/29/2009 20 20 

Il faut d'abord convertir la date colonne à la prochaine fin de mois FISCAL (par exemple 1/27/2007 -> 1/28/2009, 30/01/2009 -> 2/27/2009, etc.), puis regroupez par cette valeur.

j'ai pu utiliser:

SELECT ID 
    ,  left(CONVERT(VARCHAR(10) 
    ,  date, 111),7) as Date 
    ,  round(sum(Hours),0) as Hours 
    ,  round(sum(Weight),0) as Weight 
    FROM ... 
    GROUP BY ID 
    ,  left(CONVERT(VARCHAR(10), date, 111),7) 
    ORDER by ID ASC 
    ,  left(CONVERT(VARCHAR(10), date, 111),7) ASC 

mais que seulement les groupes par calendrier dates, non selon le mois d'exercice se termine, j'ai dans la colonne FISCAL.

+0

Quel moteur DB utilisez-vous ici? Aussi pouvez-vous poster le SQL qui retourne la première sortie. –

+0

Vous devez clarifier cette question. Fiscal dans le tableau ci-dessus est 0 pour les 12 premières entrées, alors comment ces dates sont-elles calculées? L'heure et le poids sont-ils en quelque sorte liés au calcul du mois fiscal? Regroupons-nous plusieurs lignes pour calculer une seule ligne (par exemple, joindre des entrées AAA sur plusieurs lignes pour déterminer le mois fiscal réel)? Réduire au problème de base ... – razzed

+0

La première étape consiste à obtenir les données dans deux tables distinctes. Vous voulez que la deuxième table représente les mois fiscaux, avec une date de début et une date de fin pour chacun d'eux. Sortir cela de la confusion ALL UNION ci-dessus est stupide - beaucoup trop dur travail. Avec cette table disponible, le regroupement devient assez simple; vous regroupez par fin fiscale et vous vous joignez à 'dateval BETWEEN fiscal_start AND fiscal_end'; la gamme inclusive de BETWEEN/AND est très utile ici. –

Répondre

1

Vous ne devez pas réunir les dates fiscales dans votre table. Mais avec la table comme vous l'avez maintenant, vous pouvez d'abord créer une table (en utilisant WITH, donc pas de privilèges spéciaux sont nécessaires) avec les 'périodes' fiscales et rejoindre cette table avec votre table principale.

J'ai appelé votre table SO. J'ai aussi dû renommer vos colonnes en cHour et CDate car dans Oracle au moins Date est un mot réservé. Vous pouvez créer très probablement la table « principale » et le tableau « fiscal » directement à partir de vos tables source pour accélérer les choses:

with fiscal_part as (
      select fiscal 
      from SO 
      where fiscal is not null) 
, fiscal as (
      select fb.fiscal   fiscal_begin 
      ,  min(fe.fiscal) fiscal_end 
      from fiscal_part fb right join 
        fiscal_part fe 
       on fe.fiscal > fb.fiscal 
      group by fb.fiscal) 
, main as (
      select * 
      from SO 
      where fiscal is null) 
select main.ID 
,  fiscal.fiscal_end 
,  sum(main.cHour) 
,  sum(main.weight) 
from main 
join fiscal on main.cdate >= coalesce(fiscal.fiscal_begin, main.cdate) 
      and main.cdate < fiscal.fiscal_end 
group by main.ID 
,  fiscal.fiscal_end 
order by fiscal.fiscal_end 

Notez également que vos données d'échantillon a une erreur; le poids de votre dernière période devrait être de 40 (les rangées avec les dates 2/27 et 2/28).