Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Multiple Sum columns in different tables

Posted on 2015-02-18
8
94 Views
Last Modified: 2015-02-25
I have the following two tables

Table: Daily

Product     Date1             OrderNumber    Boxes
A                 01/05/2015          123                        5
A                01/06/2015           234                        1
A                01/07/2015           235                        1
C                01/15/2015           345                        2
C                01/16/2015           456                        4
D                02/01/2015           567                         7
D                01/02/2015      678                         3
D                01/02/2015      689                         3

Table: TBF

Product            Week      Year      Boxes   Period
A                         1               2015      4             1
A                         1               2015      4             2
C                         2               2015      1             1
C                         2               2015      3             2
D                         5               2015      5             1      
D                         5               2015      10            2

I need the sum the boxes in Daily grouping by year, weeknumber and product. I then need to sum the boxes in FC for the same Week, year and product.

This is the query I have but its giving the wrong number for Sum(Boxes) in TBF

SELECT Daily.PRODUCT, Year(Daily.DATE1) AS DYear, Val(Format(Daily.DATE1,"ww",1,2)) AS DWeek, Sum(Daily.[BOXES]) AS DBOXES,
Sum(TBF.BOXES) AS SumOfBOXES
FROM Daily LEFT JOIN TBF
ON (((TBF.PRODUCT)=[Daily].[Product]) AND ((TBF.YEAR)=Year([Daily].[DATE1])) AND ((TBF.WEEK)=Val(Format([Daily].[DATE1],"ww",1,2))))
GROUP BY Daily.PRODUCT, Year(Daily.DATE1), Val(Format(Daily.DATE1,"ww",1,2));
0
Comment
Question by:Angel02
8 Comments
 
LVL 33

Accepted Solution

by:
ste5an earned 350 total points
ID: 40617051
Create two queries to sum each table seperatly. Then join those two queries.

Another option would be using a sub-query instead of the JOIN. E.g.

SELECT  Daily.PRODUCT ,
        YEAR(Daily.DATE1) AS DYear ,
        Val(FORMAT(Daily.DATE1, "ww", 1, 2)) AS DWeek ,
        SUM(Daily.BOXES) AS DBOXES ,
        ( SELECT    SUM(TBF.BOXES)
          FROM      TBF
          WHERE     TBF.Product = Daily.PRODUCT
                    AND TBF.[Year] = YEAR(Daily.DATE1)
                    AND TBF.[Week] = Val(FORMAT(Daily.DATE1, "ww", 1, 2))
        ) AS Expr1
FROM    Daily
GROUP BY Daily.PRODUCT ,
        YEAR(Daily.DATE1) ,
        Val(FORMAT(Daily.DATE1, "ww", 1, 2));

Open in new window

0
 

Author Comment

by:Angel02
ID: 40617130
sub query seems very slow. And the results are hanging the database.
Can you please give me a sample of join?
0
 

Author Comment

by:Angel02
ID: 40617176
Got it. This is how I did it. Please let me know if any improvements.

Select TDaily.product, TDaily.DYear, TDaily.DWeek,TDaily.DBOXES, FC.FCBoxes from (SELECT Daily.product, YEAR(Daily.DATE1) AS DYear, Val(FORMAT(Daily.DATE1, "ww", 1, 2)) AS DWeek, SUM(Daily.BOXES) AS DBOXES
FROM Daily
GROUP BY Daily.product, YEAR(Daily.DATE1), Val(FORMAT(Daily.DATE1, "ww", 1, 2))) As TDaily
LEFT JOIN  (SELECT    product, [year], [week], SUM(BOXES) As FCBoxes
          FROM      TBF
          Group by product,[Year], [Week]) As FC
          ON    FC.product = TDaily.product
                    AND FC.[Year] = (TDaily.DYEAR)
                    AND FC.[Week] = TDaily.DWeek
0
MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

 
LVL 49

Assisted Solution

by:Gustav Brock
Gustav Brock earned 150 total points
ID: 40617446
That won't do because year-week does not exactly match the calendar year around New Year.
Also, it is much simpler to join via a where clause.
This will work for any date (air code):

Select
    ISO_WeekNumber([Date1],
    Daily.Product,
    Sum(Daily.Boxes) As SumDailyBoxes,
    Sum(TBF.Boxes) As SumTBFBoxes
From
    Daily,
    TBF
Having
    Daily.Product = TBF.Product
    And
    ISO_WeekNumber([Date1]) = TBF.Year & "W" & Right("0" & TBF.Week, 2)
Group By
    Daily.Product,
    ISO_WeekNumber([Date1])

Public Function ISO_WeekYearNumber( _
  ByVal datDate As Date, _
  Optional ByRef intYear As Integer, _
  Optional ByRef bytWeek As Byte) _
  As String

' Calculates and returns year and week number for date datDate according to the ISO 8601:1988 standard.
' Optionally returns numeric year and week.
' 1998-2007, Gustav Brock, Cactus Data ApS, CPH.
' May be freely used and distributed.

  Const cbytFirstWeekOfAnyYear  As Byte = 1
  Const cbytLastWeekOfLeapYear  As Byte = 53
  Const cbytMonthJanuary        As Byte = 1
  Const cbytMonthDecember       As Byte = 12
  Const cstrSeparatorYearWeek   As String = "W"
  
  Dim bytMonth                  As Byte
  Dim bytISOThursday            As Byte
  Dim datLastDayOfYear          As Date

  intYear = Year(datDate)
  bytMonth = Month(datDate)
  bytWeek = DatePart("ww", datDate, vbMonday, vbFirstFourDays)
  
  If bytWeek = cbytLastWeekOfLeapYear Then
    bytISOThursday = Weekday(vbThursday, vbMonday)
    datLastDayOfYear = DateSerial(intYear, cbytMonthDecember, 31)
    If Weekday(datLastDayOfYear, vbMonday) >= bytISOThursday Then
      ' OK, week count of 53 is caused by leap year.
    Else
      ' Correct for Access97/2000+ bug.
      bytWeek = cbytFirstWeekOfAnyYear
    End If
  End If

  ' Adjust year where week number belongs to next or previous year.
  If bytMonth = cbytMonthJanuary Then
    If bytWeek >= cbytLastWeekOfLeapYear - 1 Then
      ' This is an early date of January belonging to the last week of the previous year.
      intYear = intYear - 1
    End If
  ElseIf bytMonth = cbytMonthDecember Then
    If bytWeek = cbytFirstWeekOfAnyYear Then
      ' This is a late date of December belonging to the first week of the next year.
      intYear = intYear + 1
    End If
  End If
  
  ISO_WeekYearNumber = CStr(intYear) & cstrSeparatorYearWeek & Format(bytWeek, "00")

End Function

Open in new window

/gustav
0
 

Author Comment

by:Angel02
ID: 40617571
The query wouldn't work for me because table TBF does not have all the products that Daily has and also its calculating the SumTBFBoxes wrong.
Ill however use ISO_WeekYearNumber in my query. Thanks for the idea.
0
 
LVL 49

Expert Comment

by:Gustav Brock
ID: 40617583
> ..  table TBF does not have all the products that Daily has ..

OK, couldn't see that from the example data. Then you need an outer join.

/gustav
0
 
LVL 48

Expert Comment

by:PortletPaul
ID: 40618168
Regarding the data

> if table Daily can have a product X that isn't in TBF; can TBF have a product Y that is not in Daily?
> could TBF have year & week information that isn't in Daily?

------------
@gustav
>>" it is much simpler to join via a where clause."
Oh, goodness, I so disagree. Mixing filtering predicates with join logic can be ever so confusing but ANSI join syntax clearly differentiates them.

also:
HAVING is usually performed after the GROUP BY, did you mean to use WHERE? could just be an "air code error" :)
0
 
LVL 49

Expert Comment

by:Gustav Brock
ID: 40618272
Yes.

/gustav
0

Featured Post

Migrating Your Company's PCs

To keep pace with competitors, businesses must keep employees productive, and that means providing them with the latest technology. This document provides the tips and tricks you need to help you migrate an outdated PC fleet to new desktops, laptops, and tablets.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you have heard of RFC822 date formats, they can be quite a challenge in SQL Server. RFC822 is an Internet standard format for email message headers, including all dates within those headers. The RFC822 protocols are available in detail at:   ht…
Composite queries are used to retrieve the results from joining multiple queries after applying any filters. UNION, INTERSECT, MINUS, and UNION ALL are some of the operators used to get certain desired results.​
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which …
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

792 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question