SQL GROUP BY total cost of each week of the year
OK, so I'm doing some access here and I can't figure it out, tried a lot already but nothing comes close. And I hope some of you know what to do.
I have multiple tables in my database (just for school)
Products table
Type Price Color Height Model
--------------------------------------------
KL47 69 B 150 Dames Normal Model
VRS02 73 W 170 Heren Smal Model`
Copy Table - Products
Copienr Type
------------------------
K664 KL47
T553 KL47
V3553 VRS02
V7744 VRS02
V9941 VRS02
Custumers table
Customrnr Companyname Adress
-----------------------------------------
1 Jiver Posthoorn 27
2 Veco Weebosserweg 21
3 V&D Omabakfietsjes 74
And finally, a table to check the witch's customer rents the witch's product
Rentnr Customernr Copienr Date-from Date-Till
-------------------------------------------------------
5 3 K664 11/5/2014 11/29/2014
6 3 T553 10/7/2014 12/13/2014
7 3 V3553 11/18/2014 12/19/2014
8 3 V3553 4/8/2015 8/12/2015
9 3 V7744 4/8/2015 7/8/2015
10 3 T553 5/4/2015 6/8/2015
Now I need a table of all the products that V&D has rented this year. Group at a total price per week.
I have this so far:
SELECT t.typen, c.copienr, date-from, date-till, companyname, price
FROM typen t, copies c, rented-vieuw r, customers c
WHERE bedrijfsnaam = 'V&D'
AND c.customernr = r.customernr
AND r.copienr = c.copienr
AND c.type = t.type
AND date-from >= #1/1/2015#;
Next, for grouping by the total weekly cost of the weekly, I tried a lot. Thinks it doesn't even make any sense, but I can't figure it out. Hope you can help me. Thank!
Edit: the price in the product table is the rental price of the product / weak ***
So here is my first attempt at an answer online,
My understanding of your questions is that you are trying to create a query with only one company's products this year only. And get the total price for this product.
I assumed your price was weekly. I added two columns so you can understand what I did, total days and full weeks. Also I named your tables Products, Copiers - Products, Custumers, and Rentals based on the writing and descriptions you gave
SELECT Renting.Rentnr, DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till]) AS NumberDays, DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till])/7 AS NumberWeeks, Custumers.Companyname, Products.Type, Products.Price, Renting.[Date-from], Renting.[Date-Till], Format([Products]![Price]*DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till])/7,"Currency") AS Total
FROM Custumers INNER JOIN ((Products INNER JOIN [Copiers - Products] ON Products.Type = [Copiers - Products].Type) INNER JOIN Renting ON [Copiers - Products].Copienr = Renting.Copienr) ON Custumers.Customrnr = Renting.Customernr
WHERE (((Year([Renting]![Date-from]))=[Which year?]))
GROUP BY Renting.Rentnr, DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till]), DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till])/7, Custumers.Companyname, Products.Type, Products.Price, Renting.[Date-from], Renting.[Date-Till], Format([Products]![Price]*DateDiff("d",[Renting]![Date-from],[Renting]![Date-Till])/7,"Currency");
The WHERE clause is used to restrict the selected year, you can change [Which year?]
to Now()
to automatically select the current year based on the computer's system time / date.
Adding also AND ((Custumers.Companyname)=[Which Company?]))
to operator WHERE
also allows you to select another company based on the company name
Hard-coded values ββlike year and company mean there is only one option for your request and you need a new request for each year and company.
Hopefully I hit the mark or get close to it.
Edit:
I understand that I didn't explain all this correctly:
DateDiff(...
used to get the difference between two dates, "d" means that after days I could also use "ww" to find out how many weeks are between dates, the next two fields are your field dates.
All joins were made automatically because I linked all tables in the relationship window. And this query was designed in the project view without using the SQL editor.
source to share
You will need a list of weeks from the first date to the last date. Also, you will need the ISO year as this may be different from the calendar year.
First, create a table Number
with one field: Number
. Make this your main index.
Fill this in with ten entries from 0 to 9.
Then create a query DateFirstLast
that will take the first and last date as parameters:
PARAMETERS
DateFirst DateTime,
DateLast DateTime;
SELECT
DateAdd("d",[Hundred]![Number]*100+[Ten]![Number]*10+[One].[Number],[DateFirst]) AS [Date]
FROM
[Number] AS One,
[Number] AS Ten,
[Number] AS Hundred
WHERE
DateAdd("d",[Hundred]![Number]*100+[Ten]![Number]*10+[One].[Number],[DateFirst])<=[DateLast];
Now, use this as a source in a new request to generate ISO year-year numbers:
SELECT
DateFirstLast.Date,
ISO_WeekYearNumber([Date]) AS YearWeek
FROM
DateFirstLast;
This list contains dates and year-week numbers for dates.
For example, in 2012 it will be from 2011W52
to 2013W01
.
Week number calculation function:
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
List of dates and weeks that you can combine with your sales data and apply grouping as needed.
source to share