Getting the Max In Different Years - ms-access

I am pulling together a table of training data for employees who took various training courses between 2010 and 2013. I am getting the counts by course. Some training an employee can accidentally register for multiple times in one year, I just need the individual employee counts. Some training however is required to be taken each year or every other year, I am trying to get the max date for each training completed for each year, so in case someone did take a course one year and then again a year later, both of them are counted. The code I have so far is,
SELECT [Training_GEMS].JOB_CLS_CD_DSC_TE, [Training_GEMS].TNG_NA, [Training_GEMS].TNG_SYS_NR, [Training_GEMS].JOB_CLS_CD, sum(iif(Max_Date BETWEEN #1/1/2010# AND #12/31/2010#,1,0)) AS 2010, sum(iif(Max_Date BETWEEN #1/1/2011# AND #12/31/2011#,1,0)) AS 2011, sum(iif(Max_Date BETWEEN #1/1/2012# AND #12/31/2012#,1,0)) AS 2012, sum(iif(Max_Date BETWEEN #1/1/2013# AND #12/31/2013#,1,0)) AS 2013
FROM Training_GEMS
GROUP BY [Training_GEMS].JOB_CLS_CD_DSC_TE, [Training_GEMS].TNG_NA, [Training_GEMS].TNG_SYS_NR, [Training_GEMS].JOB_CLS_CD;
I have the SUM IIFs setup, I am just trying to get the max for each year.

Add the following four lines (after adding comma to last SUM ... 2013 field)
Max(Iif(max_date BETWEEN #1 / 1 / 2010 #
AND #12 / 31 / 2010 # , max_date, null)) AS 2010max,
Max(Iif(max_date BETWEEN #1 / 1 / 2011 #
AND #12 / 31 / 2011 # , max_date, null)) AS 2011max,
Max(Iif(max_date BETWEEN #1 / 1 / 2012 #
AND #12 / 31 / 2012 # , max_date, null)) AS 2012max,
Max(Iif(max_date BETWEEN #1 / 1 / 2013 #
AND #12 / 31 / 2013 # , max_date, null)) AS 2013max

Something like this may require two steps. The first would be as you describe in eliminating any people that took a course more than once in a year.
Select UserID, Year(CourseDate) as CourseYear, Course, Max(CourseDate) as CourseDate
From Training_Gems
Group by Year(CourseDate), UserID, Course;
You can get the year from a date using the Year() function without having to create a new column for each year with an IIF.
Once you have your first results you can use them in a second sub-query like so.
select Count(Course), Course From
(Select UserID, Year(CourseDate) as CourseYear, Course, Max(CourseDate) as CourseDate
From Training_Gems
Group by Year(CourseDate), UserID, Course) as t1
Group By Course;

Related

MySQL equation(WHERE clause)

I am trying to use create a graph using last months sales (plus 10% of last months production so multiplying the last months sales by 1.1). It seems it should be simple but I can't seem to figure it out, I have tried using a CASE statement
CASE
WHEN MonthName(SaleDate) = 'Jan' THEN Count(SaleId) -- how do we limit for a particular time frame in a CASE?
I am using the MySQL version 5.7, but I am using DOMO so I can't be sure but 5.7 was the documentation they linked to
SELECT
SUM(CASE WHEN MonthName(SaleDate) = 'Jan' THEN SaleAmount END) "January Sales)
FROM my_table
NB
If you don't specify the year you could have the total of sales from January 2021 + January 2022.
I assume that the column salesId is not the value of the sale.
I suspect that the function month() could run faster than monthname(). WHEN MONTH(SaleDate) = 1

SQL code for counting consecutive years - syntax error msg in code

I'm a heavy MS Access user, but still a novice with SQL. I need to count consecutive years in a table and am attempting to use SQL code provided on a previous post in Stack in order to count consecutive years by ID. My table name is "TEMP" and two field names are "ID" (ten-digit field stored as short text) and a 4-digit field named "YEAR" (stored as a number). I'm attempting to use a solution provided at Sql query to Count Total Consecutive Years from latest year but I'm getting a syntax error in the code on "over"
A sample of the data:
ID YEAR
0363267020 1982
0374650010 1982
0395373010 1982
0397175020 1982
0427746010 1982
0435187010 1985
0435187010 1984
0435187010 1982
0445237010 2017
0445237010 2016
0445237010 2015
0445237010 2014
0445237010 2013
0445237010 2012
0445237010 2010
0445237010 2009
0445237010 2008
0445237010 2005
The overall solution is to enable a count of consecutive of giving. So for above, the first 8 IDs wouldn't yet any counts, but the 9th ID would yield a result of 9. Is anyone able to assist?
In the end, I could export to Excel, but then it becomes a much more manual process and I'm hoping to build something that is more automatic (the table has more than 20,000 records).
I've also tried the following module, but am having trouble building a query to pull the data out.
Option Compare Database
With CurrentDb.OpenRecordset("TEMP")
Do Until ID.EOF
If !YEAR = strPrevious Then
Debug.Print strPrevious, lngCount
lngCount = 0
Else
strPrevious = !YEAR
lngCount = lngCount + 1
End If
Loop
End With
CODE from Sql query to Count Total Consecutive Years from latest year
select ID,
first_value(year) over (partition by ID order by year desc) - year +1 as x,
row_number() over (partition by ID order by year desc) as rn
from Temp
with cte as
(
select ID, year,
first_value(year) over (partition by ID order by year desc) - year + 1 as x,
row_number() over (partition by ID order by year desc) as rn
from Temp
)
select ID,
sum(case when year <> 0 then 1 else 0 end)
from cte
where x = rn
group by ID
I get the syntax error in the SQL query code. When I have attempted a query to work with the module, I continue to receive various error messages.

SSRS - calculate percent change with variable years and number of years

Hopefully, I can explain this clearly! Our report allows user to select a variable number of academic years. They can be consecutive or not. In this case, say the user selects 2017, 2015, 2013. The report presents like this:
AcYear TotCredits %Change
2013 251 0.00
2015 255 0.00
2017 1102 0.00
Because the SQL that provides the datasource is assuming the previous year is one year prior. So 2015 is being compared against 2014, even though we're not selecting that info, which is why it's 0. 2017 is being compared against 2016, even though the user selected 2015. So, either in the initial SQL or in the report table expression, how would I go about getting the credits for the most immediately prior SELECTED academic year, no matter how many were selected, and then calculating the percent change based on that??
(If the user selected consecutive years, say 2017 and 2016, the data looks like this:)
AcYear TotCredits %Change
2016 458 0.00%
2017 19 -95.85%
This is the self join to get the "previous" year:
from
cte
left join cte as prev1
on cte.academic_year - 1 = prev1.academic_year
and cte.subject = prev1.subject
Thanks for any ideas!
You could try to use previous function to see whether it works or not. You need to make sure Year has been sorted. Below is design
select * from (select 2012 as year, 12 as amount
union all
select 2013 as year, 5 as amount
union all
select 2014 as year, 6 as amount
union all
select 2015 as year, 4 as amount
union all
select 2016 as year, 24 as amount)tt
where year in (#t)
Expression:
=iif(Fields!year.Value-previous(Fields!year.Value)=1,(Fields!amount.Value-previous(Fields!amount.Value))/iif(IsNothing(previous(Fields!amount.Value) ), 0,previous(Fields!amount.Value)),0)
Then you will get the result like below
Zoe
Surprisingly easy/elegant fix, just took me a long time to find it. The original import bit:
SELECT
cte.academic_year
, cte.subject
, cte.subject_desc
, cte.credits as cur_credits
, prev.credits as prev_credits
FROM
cte
LEFT JOIN cte as prev
on cte.academic_year - 1 = prev.academic_year
and cte.subject = prev.subject
The new improved code:
SELECT
t.academic_year
, t.subject
, t.subject_desc
, t.credits as cur_credits
, prev_credits = prev.credits
FROM
cte t
OUTER APPLY
(SELECT top 1 credits from
cte
WHERE t.academic_year > academic_year
and t.subject = subject
ORDER BY academic_year desc) prev
It would have been very nice to use LAG, but alas, we are on SQL2008.

adding row value to total if condition (don't know how to ask this)

I'm running a points system for companies where every employee that works for that company is worth some points.
Every month the points for the companies are calculated.
This works so far, however In the 9th month of this year I would like to give double points for each acquired employee in that month.
I don't know how to do that.
I have this query now:
SELECT company, (employees *2) as "Points"
FROM data
WHERE month = '10'
GROUP BY company
But as you can see I give 2 points for each employee that works for that company in that month.
But for month 9 I want to give double points and add them to current points in current month(10)
I have this SQLfiddle as example: http://sqlfiddle.com/#!9/2cb812/7
Expected result:
company Points
__________________
company 1 26 + (extra points from month 9)
company 2 32 + (extra points from month 9)
company 3 44 + (extra points from month 9)
So it's all about the August/September delta 2018. If you run the query for any month before September 2018 (June 2018, May 2012, whatever), you just want to get the current month's points. If you run the query for any month after August 2018 (December 2018, March 2022, ...) you want the 2018 bonus points added.
Group by company and use conditional aggregation (an aggregation function on a condition) in order to calculate this.
We must look at the requested month (e.g. 10/2018) and August 2018 and September 2018.
SET #yearmonth = '201810';
SELECT
company,
SUM(
CASE WHEN yearmonth = #yearmonth THEN employees * 2 ELSE 0 END +
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201809' THEN employees * 4 ELSE 0 END -
CASE WHEN #yearmonth >= '201809' AND yearmonth = '201808' THEN employees * 4 ELSE 0 END
) AS points
FROM data
WHERE yearmonth in ('201808', '201809', #yearmonth)
GROUP BY company
ORDER BY company;
The WHERE clause is superfluous, as the months are checked inside the SUM function, but it may speed up the query.
Rextester demo: https://rextester.com/ELOWTL44361

Grouping months by quarter over multiple years depending on a dynamic start month

Using MySQL and PHP I am building a JSON array to populate a data table.
For the purposed of my question suppose the data table has the following columns:
Year: 2010,2011,2012,2013...<br/>
Month: 1,2,3,4,5...<br/>
Value: 100, 150, 200 etc...<br/>
The table structure cannot be altered and my solution needs come into the MySQL query
The data can be viewed either monthly, quarterly or yearly. Monthly and yearly is achieved easily through grouping by year and month.
Quarterly data can be grouped by calendar quarter (Jan-Mar, Apr-Jun, Jul-Sep, Oct-Dec) by this group statement:
GROUP BY year, round((month/3)+0.3,0)
So where Jan, Feb and March might all have 100 for their value the summed result is 300, same for other months.
Now my problem comes when I want to group values by a financial quarter, for example a quarter that starts in Feb, or any other quarters.
I have a statement that works for the quarter grouping using two variables that can be accessed via the SQL query, start_year (i.e. 2014) and start_month (i.e. 2)
GROUP BY year, (((round(((((month-(start_month-1))+((year-start_year)*12))-((year-start_year)*12))/3)+0.33,0)/4)+4)-floor(((round(((((month-(start_month, '%m')-1))+((year-start_year)*12))-((year-start_year*12))/3)+0.33,0)/4)+4)))*12
which basically will assign a 0,3,6,9 value to each calendar month for the purposes of grouping.
In the financial year starting February this works fine for quarters 1-3, however breaks for the final quarter as it includes Nov and Dec 2014 data and Jan from 2015.
As a result I get 5 rows of data instead of 4.
This is because of the preceding GROUP by year clause, an important addition as we might want to generate a table that views sequential quarters for multiple years.
So what I am looking for is a way of grouping the years together by offsetting the start month.
So when the year starts in Jan it will group Jan-Dec but if we change that to starting Feb it will group Feb-Jan.
Any ideas, suggestions most welcome!
Regards,
Carl
I solved a similar problem just now (a Moodle report aggregating assignment scores by year and quarter) with something like this:
select year(from_unixtime(s.timemarked)) as year, quarter(from_unixtime(s.timemarked)) % 4 + 1 as quarter, count(distinct data1) as "tickets graded" from mdlassignment_submissions s where grade >= 0 group by year, quarter order by year, quarter;
The relevant part for what you're doing is quarter(from_unixtime(s.timemarked)) % 4 + 1 as quarter
As another commenter pointed out, MySQL has a quarter() function, but it doesn't do financial quarters. However, since (as I understand it, at least, based on consulting the relevant wikipedia page) financial quarters are just offset by 1, the % 4 + 1 at the end should convert it.