I am a newbie in programming and trying to add some automation in my team to help with daily operation.
I try to create a function to create interest payment schedule according to given start date, end date and intervals. For example, for a one-year security with start date 2017/01/14, maturity date 2018/01/14, payment frequency is every 3 months. it has 4 interest period: 2017/01/14 - 2017/04/14, 2017/04/14 - 2014/07/14, 2017/07/14 - 2017/10/14, 2017/10/14 - 2018/01/14. I want to create a date table to display these 4 periods in Access.
The record should look like below:
seq startdate enddate
1 2017/01/14 2017/04/14
2 2017/04/14 2017/07/14
3 2017/07/14 2017/10/14
4 2017/10/14 2018/01/14
Could anyone help me with this?
Thanks a lot.
You can use the MSysObjects table and a Cartesian query to create this:
PARAMETERS
Period Text ( 255 ),
Periods Short,
FirstDate DateTime;
SELECT DISTINCT
10*Abs([Deca].[id] Mod 10)+Abs([Uno].[id] Mod 10)+1 As Sequence,
DateAdd([Period],[Sequence]-1,[FirstDate]) AS [DateStart],
DateAdd([Period],[Sequence],[FirstDate]) AS [DateEnd]
FROM
MSysObjects AS Uno,
MSysObjects AS Deca
WHERE
10*Abs([Deca].[id] Mod 10)+Abs([Uno].[id] Mod 10)<[Periods]
Run this with the parameters:
Period: q
Periods: 4
FirstDate: 2017-04-14
Related
I have a sample table here with the following columns and sample records. I want to be able to sum my column cases using with a specific date range (the helper column).
I want to get my results this way:
Sum all cases WHERE date range is in between 2022-03-23 - 2022-04-01 and so on.
date range
Sum of Cases
2022-03-23-2022-04-01
5 (sample result only)
2022-03-24-2022-04-02
9 (sample result only)
The logic of the date range is always n - n9 days.
I 've tried this type of query but it does not work, it there a way for me to get this without have to use a query to create another column?
SELECT Date,
sum([QUERY 1]) as "Reports 7 days prev",
sum ([QUERY 2]) as "Reports 7 days after"
FROM REPORTS
GROUP BY Date
Data:
Date
BuyerID
Cases
Helper (Date Range)
4/1/2022
20001
2
2022-03-23-2022-04-01
4/1/2022
20001
1
2022-03-23-2022-04-01
4/2/2022
20002
3
2022-03-24-2022-04-02
4/5/2022
20003
5
2022-03-27-2022-04-05
4/7/2022
20004
6
2022-03-29-2022-04-07
4/7/2022
20005
9
2022-03-29-2022-04-07
Are you looking to get total cases for last X number of days? What does your initial data look like?
you can try something like:
Step 1: You aggregate all the cases for each date.
WITH CASES_AGG_BY_DATE AS
(
SELECT Date,
SUM(Cases) AS Total_Cases
FROM REPORTS
GROUP BY Date
),
Step 2: you aggregate the last 7 days rolling cases sum for each date
LAST_7_DAY_AGG AS
(
SELECT Date, SUM(Total_Cases) OVER(ORDER BY Date ASC ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS sum_of_cases,
LAG(Date, 7) AS 7th_day
FROM CASES_AGG_BY_DATE
)
Step 3: create final output and concatenate date and 7th day before that
SELECT Date, CONCAT(Date, "-", 7th_day), sum_of_cases
FROM LAST_7_DAY_AGG;
I'm using MySQL Workbench to run my query.
I want to run a couple of different date queries, I don't know if it's possible in SQL.
1) Run the report from the first date in the system to X date.
How can I find what the first orderID or date is as part of the calculations?
I know that if I have the date to begin with, I can use:
where T5.date_purchased BETWEEN '2005-01-01' AND '2015-12-31' OR:
where T5.date_purchased BETWEEN '2005-01-01' AND CURDATE() + INTERVAL 1 DAY
UPDATE
----- Query 2 has been answered (although open to any improvement) -----
2) Run the report from the first time a product shows up, to + 6 months (to see it's first 6 months of order) ie: Widget 1 (first order) + 6 months from order date. Something like:
where widget=widgetID AND date between widget1's first purchase and +6 months
Update: This doesn't work, however this is somewhat of what I was thinking:
where (T3.products_id = 39) and DATE_ADD((T1.products_date_added), INTERVAL 1 MONTH)
I would use my P3.products_date_added, however, I don't know how to use it as part of the above, correctly.
Are either of these possible, I know how to pull the records when I know the date, I just don't know if it can be done with 'date unknown' or if I have to run a "pre-report" first. Or is it a post processing filter in excel?
Thank you in advance.
Answering problem #2:
2) Run the report from the first time a product shows up, to + 6 months (to see it's first 6 months of order) ie: Widget 1 (first order) + 6 months from order date. Something like:
where widget=widgetID AND date between widget1's first purchase and +6 months
Answer:
-- Use for specific comparisons of products OR for the first X months of sales
where (T3.products_id = 39) and T5.date_purchased between T1.products_date_added and DATE_ADD((T1.products_date_added), INTERVAL 2 MONTH)
-- This results in PID: release: 10th July, +2 months; 10th Sep. 31 units.
OR
-- (T3.products_id = 11 or T3.products_id = 39) gives the results of the 2 product orders from release date to the first 2 months of each
-- (T3.products_id) gives all products, their first 2 months of release
-- (T3.products_id = 39) gives specific product release sales
-- Inspired by: http://stackoverflow.com/questions/28788691/mysql-range-between-dates-first-order-6-months?noredirect=1#comment45853546_28788691
If it is possible for your solution, try and run 2 separate queries:
- ONE for finding the date of first order
- then calculate +6 months from query 1 result
- AND the second one to get the purchases BETWEEN both dates
I have a table that contains three things: a start number, an end number, and a date which look something like this:
table: number2day
first last day
109288787 136388928 2013-06-29
136388929 144276079 2013-06-30
144276080 147295660 2013-07-01
Given today's date, I need to find the first value from days ago so I can compare it to a number within another query
I know that there is WHERE <col-name> IN (SUBQUERY) syntax but there is a similar statement that can use operators? >,<,=?
Something like:
WHERE num >= (SELECT first FROM number2day WHERE day = SUBDATE(CURDATE(), 3))
Here I only want to check if num is greater than first from 3 days ago. Any thoughts?
The ALL keyword should work for you here:
WHERE NUM >= ALL (SELECT first FROM number2day WHERE day = SUBDATE(CURDATE(), 3))
I am currently trying to summarise some data tables into a report. Each record in the table consists of a date range, something like this:
StartDate EndDate
--------------------
13/04/13 15/04/13
17/04/13 24/04/13
28/04/13 03/05/13
05/05/13 10/05/13
Assuming the date ranges signify something like days of leave, I want to be able to calculate the total amount of days of leave per month. I came across the DatePart function which seems to work apart from one edge case: when the date range crosses a month boundary. Since the DatePart function returns the month for one given date, I am no longer able to use that to determine the amount of days of leave for that edge case record (in the example above it is record 3), since it applies to two separate months.
Ideally I want my final table to look like:
Month #OfDays
--------------------
4 11 (1st record - 2, 2nd record - 7, 3rd record - 2)
5 8 (3rd record - 3, 4th record - 5)
I've considered some messy options, such as populating a temporary table having each record signifying a different day and then doing a query on that, but I am not sure how this ties in with a report. Right now my report record source is the (incorrect) query, is it possible to have a record source as a VBA function that returns a recordsource?
Another thing I thought was to possibly to have an initial query that splits up any edge cases into two seperate records, where the date range only covers one month, and then use that for my final grouping query. Is that even possible?
I feel there may be a much simpler solution to this problem yet I can't see it.
If anyone has any ideas it would be much appreciated!
To accomplish your task using Access queries you will need to create a table named [Numbers] with a single Number (Long Integer) column named [n] containing the numbers 1, 2, 3, ... up to the highest year you expect to be working with. I created mine as follows
n
----
1
2
3
...
2499
2500
You'll also need to paste the following VBA function into an Access Module
Public Function IsValidDayOfYear(YearValue As Long, DayValue As Long) As Boolean
Dim IsLeapYear As Boolean
If (YearValue Mod 400) = 0 Then
IsLeapYear = True
ElseIf (YearValue Mod 100) = 0 Then
IsLeapYear = False
ElseIf (YearValue Mod 4) = 0 Then
IsLeapYear = True
Else
IsLeapYear = False
End If
IsValidDayOfYear = (DayValue <= IIf(IsLeapYear, 366, 365))
End Function
Let's assume that your source table is called [DateRanges]. We'll start by creating a query that generates every day of the year for each year represented in the source table. The trick here is that DateSerial() "rolls over" month boundaries, so
DateSerial(2013, 1, 32) = #2013-02-01#
and
DateSerial(2013, 1, 234) = #2013-08-22#
SELECT DateSerial(yr.n, 1, dy.n) AS [Date]
FROM Numbers yr, Numbers dy
WHERE
(
yr.n
BETWEEN (SELECT MIN(DatePart("yyyy", DateRanges.StartDate)) FROM DateRanges)
AND (SELECT MAX(DatePart("yyyy", DateRanges.EndDate)) FROM DateRanges)
)
AND (dy.n < 367) AND IsValidDayOfYear(yr.n, dy.n)
For your sample data, that query returns all days in 2013.
Let's save that query as [AllDays]. Now we can use it to extract the individual days for each date range (omitting StartDate so the final counts match yours in the question)
SELECT [Date] FROM AllDays
WHERE EXISTS
(
SELECT * FROM DateRanges
WHERE AllDays.[Date] BETWEEN DateAdd("d", 1, DateRanges.StartDate) AND DateRanges.EndDate
)
That returns the individual days corresponding to each range, i.e.,
Date
----------
2013-04-14
2013-04-15
2013-04-18
2013-04-19
2013-04-20
2013-04-21
2013-04-22
2013-04-23
2013-04-24
2013-04-29
2013-04-30
2013-05-01
2013-05-02
2013-05-03
2013-05-06
2013-05-07
2013-05-08
2013-05-09
2013-05-10
We can save that query as [RangeDays] and then use it to calculate our counts by month...
SELECT DatePart("m", [Date]) AS [Month], COUNT(*) AS NumOfDays
FROM RangeDays
GROUP BY DatePart("m", [Date])
...returning
Month NumOfDays
----- ---------
4 11
5 8
I have a MySQL db that stores orders, and has a date field that gets populated when the order reaches a certain point.
I want to create a cron job that checks for all orders where this date is in multiples of 'weeks' ago. For example:
Date stored: 12/1/2012
this row would be returned if the cron job triggered on the following days:
12/8/2012
12/15/2012
12/22/2012
12/29/2012
etc...
How do i structure the MySQL query to fetch data in this way?
You can use modular arithmetic:
SELECT * FROM my_table WHERE DATEDIFF(CURDATE(), my_date) % 7 = 0