I have the following table "detallepre".
Cuota DateCuota DatePaid Capital Interest Status
------ ---------- ---------- ------- ------- --------
1 2018-05-07 2018-05-07 722.62 265.78 -1
2 2018-06-06 2018-06-06 741.67 246.73 -1
3 2018-07-06 2018-07-07 768.64 219.76 -1
4 2018-08-05 2018-07-07 2305.92 400.00 -1
5 2018-09-04 2018-07-07 5543.42 646.63 -1
Where Quota Date is the scheduled date to pay and Paid Date is the date that the payment was made, according to the table the 1 and 2 installment was paid on the scheduled date and the 3,4 and 5 installment was paid on the same day 2018-07 -07, was the total payment of interest, the State is -1 for Paid and 1 for Debt. I want to obtain the sum of interest until the end of the month that I indicate, with an exception that I will explain at the end. For example, if I consult until June, I use the following query.
SELECT IFNULL (SUM (Interest), 0) Interest FROM detailpre WHERE DateQuota <= '2018-06-30'
result: 512.51 correct
Consult until July:
SELECT IFNULL (SUM (Interest), 0) Interest FROM detailpre WHERE DateQuota <= '2018-07-30'
result: 732.27 correct
Consult until August, this is where I have a problem.
SELECT IFNULL (SUM (Interest), 0) Interest FROM detailpre WHERE DateQuota <= '2018-08-30'
result: 1132.27 Incorrect (I say incorrect because it is not the expected result)
What I hope to get is 732.27 since the total payment date (when all the remaining installments were paid) was in July 2018-07-07, and should not continue adding the interest since the fees are paid, as it should be my query if I do it within a stored procedure, where it would indicate the Date parameter, as far as I would like it to do the calculation, sorry for my bad English, Thank you
UPDATE
I will try to explain better, what I want is to obtain the total interest until the date that I indicate (which is usually the end of the month), in the case that I consult until the month of August, September, etc onwards, I hope to obtain 732.27 as in July , since the quota 4 and 5, corresponding to August and September were already paid in July, therefore they would not add those interests and there would only be 732.27,
maybe the sql query that I put is not the correct one for this case, I use MySQL Version: 5.6.34
Thank you
Related
I'll try to provide some context so you can understand what I'm trying to achieve here. My company uses open source software to manage the employees leaves (Jorani, feel free to google it :) ).
There are different types of leave (holidays, sick leave, etc.) and we want to calculate the days "not used" from the holidays of 2016 and "copy" them to another type of leave called "Remaining Holidays 2016".
The important tables are:
entitleddays (here you specify how many days of each type you give to an employee)
id employee startdate enddate type days description
661 3 2016-01-01 2017-02-28 1 14.00 Holidays 2016
1296 3 2016-01-01 2016-12-31 4 18.00 Sick leave 2016
leaves (this table has information about the leaves taken by the employees)
id startdate enddate status employee cause duration type
2436 2016-08-01 2016-08-01 3 78 OK from managers 1.00 1
2766 2016-09-05 2016-09-12 3 63 Holidays 6.00 1
So basically we have:
Entitled leaves:
Data stored in the entitleddays table shown above. In our example let's say I have 14 days for my 2016 holidays.
Taken leaves:
Leaves taken by the user, stored in the table called leaves shown above. For our example let's say I took a day off the first of August and 6 days on September.
Available leaves:
Available days are calculated: entitled days minus "taken leaves". For this examplee, 14 entitled days - 7 = 7 days. So I still have seven days available for holidays :D
So my goal is to insert these 7 days for this user as entitled days for the new type: "Remaining days from 2016" and do this for every user. So the solution that comes up to my mind is to do something like this for every user:
INSERT INTO entitleddays (employee, startdate, enddate, type, days, description)
SELECT id, '2017-01-01', '2017-02-31', '8', (entitled holidays for 2016 minus all the taken leaves of this type), 'Remaining holidays from 2016'
FROM users
Where 8 is the new type of leave where I want to copy the days (Remaining holidays from 2016).
For example I can get the taken holidays from 2016 for a specific user doing this:
SELECT SUM(duration)
FROM leaves
WHERE employee=3 AND status=3 AND type=1
Note: Type 1 is the type of leave "Holidays 2016" and status 3 means that the leave request was accepted.
I can probably achieve all of this in a single SQL instruction but it can also be split in more if simpler or easiest to manage/understand.
Many thanks in advance.
This is how you can handle the calculation:
sum the entitleddays in a subquery by grouping the datasets in its table per employee
maybe even group by year? In this case I just filtered for 2016 via WHERE-clause
sum the taken holidays in a subquery, again by grouping per employee
group by year or filter directly for the one you need
join this subquery onto the other resultset of the other query
calculate (entitled days - taken leaves) in the outer query
Query:
SELECT
entitled.employee,
'2017-01-01',
'2017-02-31',
'8' AS type,
entitled.days - takenDays.days,
'Remaining holidays from 2016'
FROM
(
SELECT
employee,
SUM(days) AS days
FROM
entitleddays
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS entitled
LEFT JOIN (
SELECT
employee,
SUM(duration) AS days
FROM
`leaves`
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS takenDays ON takenDays.employee = entitled.employee
I am not sure if this is how you want to calculate the sums for the days of entitleddays and taken days. The query just checks if startdate >= '2016-01-01'.
Also you mentioned a table users in your attempt but didn't provide details for the table, so I left it out. I guess you could use it as a basis otherwise. In the current query the grouped result of entitleddays is the basis.
For the insert
INSERT INTO entitleddays (employee, startdate, enddate, type, days, description)
SELECT
entitled.employee,
'2017-01-01',
'2017-02-31',
'8' AS type,
entitled.days - takenDays.days,
'Remaining holidays from 2016'
FROM
(
SELECT
employee,
SUM(days) AS days
FROM
entitleddays
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS entitled
LEFT JOIN (
SELECT
employee,
SUM(duration) AS days
FROM
`leaves`
WHERE
startdate >= '2016-01-01'
AND type = 1
GROUP BY
employee
) AS takenDays ON takenDays.employee = entitled.employee
I have following record.
Employee Period from to
Dave 1 `2015-01-01` `2015-01-01`
Goliath .5 `2015-01-21` `2015-01-21`
Goliath 1 `2015-02-05` `2015-02-06`
Dave 1 `2015-01-10` `2015-01-11`
I need to calculate Period multiplied by date (from to) and arrange it by Months.
So the result would be like this.
Employee Jan_leave Feb_leave Total Leave
Dave 3 0 3
Goliath .5 2 2.5
my query which is not so correct
SELECT `employee`, (DATEDIFF(`to`, `from`)+1 *(`period`)), DATE_FORMAT(`from`, '%M') AS m
FROM `leave` GROUP BY `employee`, DATE_FORMAT(`from`, '%Y-%m')
I am giving you a query which will fulfill the demand of the aforementioned example.
SELECT
employee,
SUM(CASE WHEN MONTH(`from`)=1 THEN ((DATE(`to`)-DATE(`from`)+1) * period) ELSE 0 END) AS Jan_leave,
SUM(CASE WHEN MONTH(`from`)=2 THEN ((DATE(`to`)-DATE(`from`)+1) * period) ELSE 0 END) AS Feb_leave,
SUM( (DATE(`to`)-DATE(`from`)+1) * period) AS Total_leave
FROM `leave`
GROUP BY employee
But you have to think further to make some modifications on this query.
Further issues to consider :
If the from and to date range overlaps in two consecutive months then what will you do?
EXAMPLE : Suppose An employee took a leave from February 27 to March 3. Then for this date range February leave should be 2 and March leave should be 3 (Let's assume the year is not a leap year)
If data of different years exist then you won't get the correct result etc.
SUGGESTION :
I would suggest you to think further on the above cases and change the query thereby.
It will be a great pleasure for me as well as for you if you can modify the query so the query can be applicable to all possible scenarios.
GOOD LUCK!
Table name: activity
Field name: ProcessYM
I have mysql data like below.
ProcessYM
==========
201312
201311
201310
201309
201308
201307
201306
201305
201304
201303
201302
201301
201212
201211
201210
201209
201208
201207
201206
I want to fetch the result like below. I mean, the mysql query to fetch the every quarter of the year like 201312, 201309, 201306, 201303, 201212, 201209.. and so on.
Actual Output I expect
=======================
ProcessYM
201312
201309
201306
201303
201212
201209
201206
I have tried the below query, but it does not produce the expected result.
SELECT distinct `ActProcessYM` from `activity` where `ActProcessYM`%3=0 order by ActProcessYM desc
Output of above query
=====================
201312
201309
201306
201303
201210
201207
It is much appreciated for your smart reply.
You need to modulo of the month part only. Your query is implicitly casting your ProcessYM as an INT.
For example:
SELECT DISTINCT ProcessYM
FROM activity
WHERE RIGHT(ProcessYM,2)%3=0
ORDER BY ProcessYM DESC
fiddle
you should retrieve the last two digits from field value and do the logic as you are doing.
SELECT distinct `ActProcessYM` from `activity` where substring(ActProcessYM,5,2)%3=0 order by ActProcessYM desc
Here's a not-so-quick-and-dirty way of handing this date processing. I believe you're looking for a MySQL formula like this:
yyyymm = TRUNC_QUARTER(yyyymm)
That is, you are looking for a function that converts any yyyymm month notation into a notation that shows the month that ends the quarter in question.
Let's start with an expression that converts any particular DATETIME expression to the DATE of the beginning of the quarter.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
This takes a timestamp (e.g. '2011-04-20 11:15:01') and turns it into the date of the starting of the quarter. (e.g. '2011-04-01')
Having things in this date form is helpful because you can use them for date arithmetic. For example, you can get the last day of that quarter like this.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
+ INTERVAL 1 QUARTER - INTERVAL 1 DAY
Here's a writeup on all this: http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
I've found it helpful to try to stick to the date datatype when processing time series data.
You need to separate out the month value before doing the modulo 3 (% 3). Doing a modulo 100 first will do it:
(ProcessYM % 100) % 3) = 0
or
mod(mod(ProcessYM,100),3) = 0
Try this,
SELECT distinct `ProcessYM` from `activity` where SUBSTRING(`ProcessYM`,5,2)%3=0 order by ProcessYM desc
I am trying to develop an access based database for a small company. I have made few tables, some of them are the "2011/2012 Total Production in $" and ""2011/2012 Total Production in CY."
All four tables have a column "Actual Production"
Now, using query tool, i have to achieve two objectives.
get the maximum and minimum production of each month in a year
display the date of when the Actual Production was maximum/minimum in the month
I have accomplished first task which was simple; Make a query, get relevant fields, Summary Max & Min and finally distrubute in month wise. I.e Jan Max 5000, Min 2000...Feb Max 6000 Min 1000
Now what i desire is to display the date of max or min production for the month. So if April had MAX 181,218.00 in its month, I want it to display the date when it occurred (i,e April 10th 2012)
I am a beginner with Access, so please be as simple as possible.
Sample data gleaned from comment:
Month Sum of Prod Min Prod in $ Max Prod in $
------------- ------------- ------------- -------------
January 2011 $1,184,096.98 $20,486.40 $171,470.40
February 2011 $1,558,072.20 $44,962.20 $116,359.20
March 2011 $1,744,442.19 $19,200.00 $141,065.10
April 2011 $1,698,608.63 $27,500.70 $181,218.00
May 2011 $1,826,915.38 $37,996.00 $130,066.00
June 2011 $2,317,890.71 $42,645.00 $144,323.30
The above data were few of the fields gnerated by Query.
What I am looking for is
Month Date of Min Prod Min Prod in $ Date of Max Prod Max Prod in $
------------- ------------- ------------- ------------- -------------
January 2011 Jan 15 $20,486.40 Jan 10 $171,470.40
February 2011 Feb 20 $44,962.20 Feb 27 $116,359.20
March 2011 March 10 $19,200.00 March 1 $141,065.10
and so forth.
Is it possible to use a query to generate this result?
thanks!
Relation to the comment.
Relevant fields in one of the tables are.
Date of Activity Actual Production
------------- ------------- -------
1/3/2012 $20,486.40
1/4/2012 $44,962.20
1/5/2012 $19,200.00
I got lost in the details of your question. So I'll show you sample data and queries to get something like what I hope you want from that data.
Here is the contents of tblAbbas.
activity_date actual_production
1/3/2012 $20,486.40
1/4/2012 $44,962.20
1/5/2012 $19,200.00
2/1/2012 $3.00
2/2/2012 $2.00
2/3/2012 $1.00
Here is the SQL for a query named qryMonthStart. The purpose of this query is to determine the first day of the month which includes the activity_date.
SELECT
DateSerial(Year(activity_date),Month(activity_date),1)
AS month_start,
activity_date,
actual_production
FROM tblAbbas;
The query below uses qryMonthStart as its data source and gives me this result set.
month_year SumOf_production min_prod_date MinOf_production max_prod_date MaxOf_production
January 2012 $84,648.60 1/5/2012 $19,200.00 1/4/2012 $44,962.20
February 2012 $6.00 2/3/2012 $1.00 2/1/2012 $3.00
And the query SQL ...
SELECT
Format(grpby.month_start,"mmmm yyyy") AS month_year,
grpby.SumOf_production,
qmin.activity_date AS min_prod_date,
grpby.MinOf_production,
qmax.activity_date AS max_prod_date,
grpby.MaxOf_production
FROM
(
(
SELECT
month_start,
Sum(actual_production) AS SumOf_production,
Min(actual_production) AS MinOf_production,
Max(actual_production) AS MaxOf_production
FROM qryMonthStart
GROUP BY month_start
) AS grpby
INNER JOIN qryMonthStart AS qmin
ON
(grpby.MinOf_production = qmin.actual_production)
AND (grpby.month_start = qmin.month_start)
)
INNER JOIN qryMonthStart AS qmax
ON
(grpby.MaxOf_production = qmax.actual_production)
AND (grpby.month_start = qmax.month_start)
ORDER BY grpby.month_start;
Beware that query will fail ("data type mismatch in criteria expression") if you have Null for activity_date. The simplest way to prevent that is to clean out the Nulls then prohibit them in the activity_date column (set the Required property to Yes in table design view). If you decide you must allow Nulls in activity_date, you've got more work ahead.
Also note that query will give you multiple rows for the same month_year if the actual_production values in more than one of the daily records for that month matches the monthly minimum (MinOf_production). And the same situation will apply for the monthly maximum (MaxOf_production).
I have a query pulling the last six months of data from a table which has a column, UseDates (so as of today in June, this table has dates for December 2011 through May 2012).
I wish to include a "rank" column that associates a 1 to all December dates, 2 to all January dates, etc -- up to 6 for the dates corresponding one month prior. If I were to open up this query a month from now, the 1 would then be associated with January, etc.
I hope this makes sense!
Example, if I ran the query right now
UseDate Rank
12/31/2011 1
1/12/2012 2
...
5/23/2012 6
Example, if I ran the query in August:
UseDate Rank
2/16/2012 1
3/17/2012 2
...
7/21/2012 6
Example, if I ran the query in March:
UseDate Rank
9/16/2011 1
10/17/2011 2
...
2/24/2012 6
SELECT
UseDates,
DateDiff("m", Date(), UseDates) + 7 AS [Rank]
FROM YourTable;
You can use month function for UseDates and subtract it from the result of now function. If it goes negative, just add 12. Also you may want to add 1 since you start with 1 and not 0. Apparently it should work for half a year date ranges. You'll get into trouble when you need to "rank" several years.
You can rank with a count.
SELECT
Table.ADate,
(SELECT Count(ADate)
FROM Table b
WHERE b.ADate<=Table.ADate) AS Expr1
FROM Table3;
You have to repeat any where statement in the subquery:
SELECT
Table.ADate,
(SELECT Count(ADate)
FROM Table b
WHERE b.ADate<=Table.ADate And Adate>#2012/02/01#) AS Expr1
FROM Table3
WHERE Adate>#2012/02/01#