I have been trying to extract the number of days a particular user spent on each status in a month from the MySQL database table. The data is saved in log format which makes it a bit hard to work with. For e.g. I need to calculate the number of days the user 488 spent on each status in the month of June 2022 only.
user_id old_status new_status modified_on
488 3 10 31/05/2022 10:03
488 10 5 01/06/2022 13:05
488 5 16 07/06/2022 16:06
488 16 2 09/06/2022 08:26
488 2 6 30/06/2022 13:51
488 6 2 07/07/2022 09:44
488 2 6 08/08/2022 13:25
488 6 1 15/08/2022 10:37
488 1 11 02/09/2022 13:48
488 11 2 03/10/2022 07:26
488 2 10 10/10/2022 10:17
488 10 6 25/01/2023 17:50
488 6 1 01/02/2023 13:46
The output should look like this:
The output should look like:
user status Days
488 5 6
488 16 2
488 2 21
I tried multiple ways to join the same table with itself in order to find the solution but no luck. Any help will be appreciated.
here is what I think you should do, first join the old_status field in the log table with the status table then use the DATEDIFF function to subtract modified_on(log table ) from created_at(or any other field in status that stores creation time) you can filter results using where clause to get certain users on certain dates
this query might help (i don't know the structure of your tables so if there is something wrong edit it to suit your needs)
SELECT *,DATEDIFF(log.modified_at,st.created_at) AS spent_time_on_staus
FROM log_status AS log JOIN status AS st ON st.id=log.old_status
WHERE log.user_id=488 AND EXTRACT(MONTH FROM st.created_at) = 6
This is a suggestion to get you started. It will not get you all the way (since there are several status changes to and from the same status...)
SELECT
shfrom.userid,
shfrom.new_status as statusName,
shfrom.modified_on as fromdate,
shto.modified_on as todate,
DATEDIFF(shto.modified_on, shfrom.modified_on) as days_spent_in_status
FROM
status_history as shfrom
INNER JOIN status_history as shto
ON shfrom.userid = shto.userid and shfrom.new_status = shto.old_status
WHERE
shfrom.modified_on < shto.modified_on
;
I created a table based on your question and put in the data you provided, in mysql format:
create table status_history(
userid int,
old_status int,
new_status int,
modified_on datetime
);
insert into status_history values
(488, 3,10, '2022-05-31 10:03'),
(488,10, 5, '2022-06-01 13:05'),
(488, 5,16, '2022-06-07 16:06'),
(488,16, 2, '2022-06-09 08:26'),
(488, 2, 6, '2022-06-30 13:51'),
(488, 6, 2, '2022-07-07 09:44'),
(488, 2, 6, '2022-08-08 13:25'),
(488, 6, 1, '2022-08-15 10:37'),
(488, 1,11, '2022-09-02 13:48'),
(488,11, 2, '2022-10-03 07:26'),
(488, 2,10, '2022-10-10 10:17'),
(488,10, 6, '2023-01-25 17:50'),
(488, 6, 1, '2023-02-01 13:46');
this produces this result, where the duration is the time spent:
userid
statusName
fromdate
todate
days_spent_in_status
488
10
2022-05-31 10:03:00
2022-06-01 13:05:00
1
488
5
2022-06-01 13:05:00
2022-06-07 16:06:00
6
488
16
2022-06-07 16:06:00
2022-06-09 08:26:00
2
488
2
2022-06-09 08:26:00
2022-06-30 13:51:00
21
488
6
2022-06-30 13:51:00
2022-07-07 09:44:00
7
488
2
2022-06-09 08:26:00
2022-08-08 13:25:00
60
488
2
2022-07-07 09:44:00
2022-08-08 13:25:00
32
488
6
2022-06-30 13:51:00
2022-08-15 10:37:00
46
488
6
2022-08-08 13:25:00
2022-08-15 10:37:00
7
488
1
2022-08-15 10:37:00
2022-09-02 13:48:00
18
488
11
2022-09-02 13:48:00
2022-10-03 07:26:00
31
488
2
2022-06-09 08:26:00
2022-10-10 10:17:00
123
488
2
2022-07-07 09:44:00
2022-10-10 10:17:00
95
488
2
2022-10-03 07:26:00
2022-10-10 10:17:00
7
488
10
2022-05-31 10:03:00
2023-01-25 17:50:00
239
488
10
2022-10-10 10:17:00
2023-01-25 17:50:00
107
488
6
2022-06-30 13:51:00
2023-02-01 13:46:00
216
488
6
2022-08-08 13:25:00
2023-02-01 13:46:00
177
488
6
2023-01-25 17:50:00
2023-02-01 13:46:00
7
You still need to filter out the ones that are capturing an early status change with a later status change. I hope it gets you started.
I am trying to query a count of issues of a test that happened in the past. As a background, every year a test is done. A record is created for each "Issue" that comes up in each test. One test can have 0 to many issues. After the test is complete, those issues can be closed overtime when they're no longer issues. Each issue has a "current" status. There is also a table for tracking status changes on issues, like an audit log. When the next year comes around, the test would include any previous open issues and open additional issues. What is the correct query for finding how many issues are open in a specific test from year to year?
I.e:
2018 had 9 issues. 1 closed overtime.
2019 had 3 new issues plus the 8 still open from 2018.
Expected queries result to show 9 issues for 2018 and 11 issues for 2019.
The query below is what I have so far.
The relation of the tables are as follows.
Engagements - Has one application
Issues - One application can have many issues
Status Change - One issue can have many status changes
SELECT *
COUNT(*) as totalissues,
SUM(CASE WHEN issues.issue_type IN('EAPT','ENPT','ENVS') THEN 1 ELSE 0
end) AS externalissues,
SUM(CASE WHEN issues.issue_type IN('IAPT','INPT','INVS') THEN 1 ELSE 0
end) AS internalissues
FROM engagements
LEFT OUTER JOIN issues ON engagements.application_id = issues.application_id
LEFT OUTER JOIN status_change sc1 ON issues.id = sc1.issue_id AND issues.engagement_id != engagements.engagement_id AND date(sc1.change_date) < date(engagements.end_date)
WHERE
engagements.engagement_id = 'APT_ItemProcessingOutsourcing_DLM_2018_07'
AND (
sc1.id is null
or (
sc1.id = (
SELECT max(sc2.id)
FROM engagements e2
LEFT OUTER JOIN issues i2 ON e2.application_id = i2.application_id
LEFT OUTER JOIN status_change sc2 ON i2.id = sc2.issue_id
AND date(sc2.change_date) < date(e2.end_date)
WHERE
sc1.issue_id = sc2.issue_id
AND sc2.change_date = (
SELECT max(sc3.change_date)
FROM status_change sc3
WHERE sc3.issue_id = sc2.issue_id
AND sc3.change_date <= date(e2.end_date)
)
)
)
AND sc1.new_status not in(4,8,9,10)
);
This query has a count of 6 issues, I am expecting 9. Please let me know if you need more information.
Status change Table
id old_status new_status change_date issue_id user_id comment_id
40748721 10 1 7/18/2017 15:09 14440592 64 NULL
67384812 1 3 7/26/2018 16:43 14440592 26 13023597
67384814 7 4 7/26/2018 16:44 14440592 26 13023599
67384813 3 7 7/26/2018 16:43 14440592 26 13023598
40748722 10 1 7/18/2017 15:09 14440593 64 NULL
40748724 10 1 7/18/2017 15:09 14440595 64 NULL
40748725 10 1 7/18/2017 15:09 14440596 64 NULL
40748723 10 1 7/18/2017 15:09 14440594 64 NULL
67383070 1 3 7/26/2018 14:15 14440594 26 13023588
67383078 7 4 7/26/2018 14:16 14440594 26 13023590
67383074 3 7 7/26/2018 14:15 14440594 26 13023589
40748726 10 1 7/18/2017 15:09 14440597 64 NULL
40748727 10 1 7/18/2017 15:09 14440598 64 NULL
40748728 10 1 7/18/2017 15:09 14440599 64 NULL
40748729 10 1 7/18/2017 15:09 14440600 64 NULL
71206458 10 1 8/27/2018 11:46 23900484 26 NULL
71206459 10 1 8/27/2018 11:46 23900485 26 NULL
112852911 10 1 5/24/2019 5:07 800002498 99 NULL
112852912 10 1 5/24/2019 5:07 800002499 99 NULL
112852913 10 1 5/24/2019 5:07 800002500 99 NULL
112852914 10 1 5/24/2019 5:07 800003019 99 NULL
92704214 3 2 3/22/2019 9:39 14440593 80 16533839
92704217 3 2 3/22/2019 9:39 14440595 80 16533842
92704218 3 2 3/22/2019 9:39 14440596 80 16533843
92704219 3 2 3/22/2019 9:39 14440597 80 16533844
92704215 3 2 3/22/2019 9:39 14440598 80 16533840
92704216 3 2 3/22/2019 9:39 14440599 80 16533841
92704220 3 2 3/22/2019 9:39 14440600 80 16533845
93598047 3 2 3/24/2019 9:51 23900484 80 16548757
77165368 3 2 10/22/2018 14:28 23900485 64 14221198
93598048 3 2 3/24/2019 9:51 23900485 80 16548758
92654993 1 3 3/21/2019 1:00 14440593 1 16531378
92654994 1 3 3/21/2019 1:00 14440595 1 16531379
121160006 2 3 6/20/2019 1:00 14440595 1 17411641
92654995 1 3 3/21/2019 1:00 14440596 1 16531380
121160007 2 3 6/20/2019 1:00 14440596 1 17411642
92654996 1 3 3/21/2019 1:00 14440597 1 16531381
92654997 1 3 3/21/2019 1:00 14440598 1 16531382
92654998 1 3 3/21/2019 1:00 14440599 1 16531383
102075451 2 3 4/24/2019 8:53 14440599 99 16875917
92654999 1 3 3/21/2019 1:00 14440600 1 16531384
92655000 1 3 3/21/2019 1:00 23900484 1 16531385
102075453 2 3 4/24/2019 8:55 23900484 99 16875919
75968834 1 3 10/13/2018 1:00 23900485 1 14157115
92655001 2 3 3/21/2019 1:00 23900485 1 16531386
122784894 3 4 6/26/2019 7:40 14440595 99 17548826
122784893 3 4 6/26/2019 7:40 14440596 99 17548825
112836464 7 4 5/23/2019 23:51 14440599 80 17238673
112836465 7 4 5/23/2019 23:52 23900484 80 17238674
102075452 3 7 4/24/2019 8:54 14440599 99 16875918
102075455 3 7 4/24/2019 8:56 23900484 99 16875921
Engagement example
engagement_id application_id start_date end_date
APT_ItemProcessingOutsourcing_DLM_2018_07 735 7/16/2018 7/26/2018
Issues example
id created issue_type status_id application_id engagement_id
14440592 2017-07-18 15:09:09 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440593 2017-07-18 15:09:09 EAPT 2 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440594 2017-07-18 15:09:10 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440595 2017-07-18 15:09:10 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440596 2017-07-18 15:09:10 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440597 2017-07-18 15:09:10 EAPT 2 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440598 2017-07-18 15:09:10 EAPT 2 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440599 2017-07-18 15:09:10 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2017_03
14440600 2017-07-18 15:09:10 EAPT 2 735 APT_ItemProcessingOutsourcing_DLM_2017_03
23900484 2018-08-27 11:46:38 EAPT 4 735 APT_ItemProcessingOutsourcing_DLM_2018_07
23900485 2018-08-27 11:46:38 EAPT 2 735 APT_ItemProcessingOutsourcing_DLM_2018_07
800002498 2019-05-24 05:07:28 EAPT 1 735 APT_ItemProcessingOutsourcing_DLM_2019_04
800002499 2019-05-24 05:07:28 EAPT 1 735 APT_ItemProcessingOutsourcing_DLM_2019_04
800002500 2019-05-24 05:07:28 EAPT 1 735 APT_ItemProcessingOutsourcing_DLM_2019_04
800003019 2019-05-24 05:07:28 EAPT 1 735 APT_ItemProcessingOutsourcing_DLM_2019_04
I have some values which is based on date for different groupings
For each grouping id, what is the max of value till a particular date.
Example
Date Grouping Id Value
2017-06-01 1 100
2017-06-03 1 101
2017-06-06 1 103
2017-06-02 2 200
2017-06-04 2 210
2017-06-08 2 220
2017-06-01 2 1000
2017-06-05 2 1020
2017-06-09 2 1050
I need the output like below
Date Grouping Id Value
2017-06-01 1 100
2017-06-02 1 100
2017-06-03 1 101
2017-06-04 1 101
2017-06-05 1 101
2017-06-06 1 103
2017-06-07 1 103
2017-06-08 1 103
2017-06-09 1 103
2017-06-10 1 103
2017-06-01 2 NULL
2017-06-02 2 200
2017-06-03 2 200
2017-06-04 2 210
2017-06-05 2 210
2017-06-06 2 210
2017-06-07 2 210
2017-06-08 2 220
2017-06-09 2 220
2017-06-10 2 220
2017-06-01 3 1000
2017-06-02 3 1000
2017-06-03 3 1000
2017-06-04 3 1000
2017-06-05 3 1020
2017-06-06 3 1020
2017-06-07 3 1020
2017-06-08 3 1020
2017-06-09 3 1050
2017-06-10 3 1050
So assuming you have the TEMPLATE_TABLE that has all days x all grouping IDs data, you can try below two queries:
CREATE TABLE TABLE_1 AS
SELECT A.DATE, A.GROUPING_ID, B.VALUE
FROM
TEMPLATE_TABLE A
LEFT JOIN
GIVEN_TABLE B
ON A.DATE = B.DATE AND A.GROUPING_ID = B.GROUPING_ID
ORDER BY A.GROUPING_ID, A.DATE;
Above table TABLE_1 will pad values for matches and NULL for non-matches.
You can use this table to find maximum values till a given date for all dates through a self join given in the below query:
SELECT B.DATE, B.GROUPING_ID, MAX(A.VALUE) AS VALUE
FROM
TABLE_1 A
INNER JOIN
TABLE_1 B
ON A.GROUPING_ID = B.GROUPING_ID AND A.DATE<=B.DATE
GROUP BY B.DATE, B.GROUPING_ID;
Hope this works. Let me know if this doesn't.
The table "commissions" is of this form:
affiliate referral amount date
3 2 15 2016-08-27
1 22 10 2016-08-29
4 45 5 2016-09-06
1 33 9 2016-09-08
3 17 4 2016-09-11
2 33 10 2016-09-16
1 9 7 2016-09-26
3 17 9 2016-09-26
2 69 10 2016-09-30
1 21 7 2016-10-01
4 55 2 2016-10-06
I need to find out the ranking of the affiliates with most commissions month to month.
I have tried:
SELECT affiliate, SUM(amount) as amount
FROM commissions
GROUP BY affiliate, YEAR(date), MONTH(date)
But unfortunately it is not throwing the desired results.
Please help.
I have a table
date d_id r_id p_id q_sold onhand
2012-10-10 5 1 3025 3 10
2012-10-10 5 1 3022 12 20
2012-10-10 5 1 3023 15 33
2012-10-11 5 1 3025 3 10
2012-10-11 5 1 3022 12 20
2012-10-11 5 1 3023 15 33
2012-10-12 5 1 3025 3 10
2012-10-12 5 1 3022 12 20
2012-10-12 5 1 3023 15 33
2012-10-13 5 1 3025 3 10
2012-10-13 5 1 3022 12 20
2012-10-13 5 1 3023 15 33
2012-10-14 5 1 3025 3 10
2012-10-14 5 1 3022 12 10
2012-10-14 5 1 3023 15 33
2012-10-15 5 1 3025 3 5
2012-10-15 5 1 3022 12 5
2012-10-15 5 1 3023 15 33
I would like to get the result of the q_sold divided by average of the onhand over a 5 day period, while displaying the other data for a specific date like the 2012-10-15.
I create a query
set #stdate = '2012-10-10';
set #endate = '2012-10-15';
SELECT date, d_id,r_id,p_id,q_sold,onhand,qty_sold/AVG(qty_onhand)
FROM stp_vwsales_info_tots
WHERE date BETWEEN #stdate and #endate and d_id=5
GROUP BY d_id,r_id,p_id
But the result being showed is incorrect, it displays the data for the 2012-10-10 instead of 2010-10-15
date d_id r_id p_id q_sold onhand avg
2012-10-10 5 1 3022 12 20 0.7579
2012-10-10 5 1 3023 15 33 0.4545
2012-10-10 5 1 3025 3 10 0.3273
Can anyone help?
Use your #stdate and #endate as DATE(#stdate/#endate) or DATE_FORMAT(#stdate/#endate,'%Y-%m-%d') otherwise you have to convert #stdate/#endate from string to date through MySQL
i think what your looking for is something called a simple moving average.
to calculate this you'll need to use an inline subquery - so performance won't be the best.
assuming you want to calculate the average over the previous 5 day period, try something like this:
SELECT
date, d_id, r_id, p_id, q_sold, onhand,
( SELECT q_sold/AVG(t2.onhand)
FROM stp_vwsales_info_tots AS t2
WHERE p_id=t1.p_id AND DATEDIFF(t1.date, t2.date) BETWEEN 0 AND 4
) AS 'moving_avg'
FROM stp_vwsales_info_tots AS t1
GROUP BY t1.p_id,t1.date
order by t1.date;