How to count employees that have been promoted? - sql

I'm trying to figure out how to come up with a calculation or query to count the number of employees by grade promoted on each pay period.
*count the number of records who's value in grade have increased by pay period.
Sample solution:
Soln:
Year Payroll Period Count
2018 16 2
2019 6 1
2019 10 1
I've tried pivot and queries in access but I think this needs to have an inner join to identify specific employees who got promoted. thanks for the assistance.
code in excel that seems to work but needs to be transferred in access due to the number of records. I think inner join would make this work. =AND(B2<>B3,C2=C3,D3>D2)

Based on EXCEL, you can derive your solution, assuming that your records are in sequence for columns Year, Payroll, Employee & Grade.
Add another column to determine if there is a grade increase for that particular Payroll Period.
For excel cell reference sake, "Year" is in cell A1
Set formula of 1st cell of this column to false
For the next cell in this new column, set it as such:
The above checks if there is a grade increase for that particular Payroll Period.
The explanation of the formula in sequence is as such, 1. Check if year same (A3=A2), 2. Check if Payroll Period is different(B3<>B2), 3. Check if Employee is the same (C3=C2) and finally 4. Check if there is a change in grade (D3=D2).
Copy this formula down to the rest of your range.
Next, you can start to pivot.
Add your pivot table from your table/range with the following
Filter Grade Increase to true and also change the values aggregation of Employee from Sum to Count.
You will get the following:
I would rename Count of Employees to make it more meaningful.
One caveat for the above approach is that if the grade was increased at the beginning of the 1st Payroll Period of the year, the increase won't be captured. For such, you can remove the year check from the formula A3=A2.
Edit:
Doing a bit of research, perhaps you can do
select t1.*, (t1.Grade > t2.Grade) as Grade_Increase
from YourTableName t1 left join YourTableName t2 on
t1.Employee = t2.Employee and
(((t1.Year - 2018)*26) + t1.Payroll_Period) =
(((t2.Year - 2018)*26) + t2.Payroll_Period - 1) -- -1 to get the prior record to compare grades
What the above does is essentially joining the table to itself.
Records that are 'next in sequence' are combined into the same row. And a comparison is done.
This was not verified in Access.
Substitute 2018 with whatever your base year is. I'm using 2018 to calculate the sequence number of the records. Initially I thought of using common table expressions, rank and row_number. But access doesn't seem to support these functions.

Related

SQL query for percentage change compared to previous date

I have a table within access containing the performance of departments on different reference dates. All data is within one table "tblmain". The table contains the following fields:
reference date (called "ref_date", formatted dd.mm.yyyy)
department identifier (called "dep_id")
performance value (called "val")
Every reference date consists of round about 100 departments and every week I import a new reference date.
My goal now is to build a query which calculates the percentage change from on reference date compared to the previous reference date. Furthermore, it should only show the departments with a change bigger than 5%.
I am currently stuck. I have created a query that gives me the val from the previous reference date but only for one specific department. And I do not know how to continue. This query looks as follows:
SELECT TOP 1 tblmain.val
FROM (SELECT TOP 2 tblmain.val, tblmain.ref_date FROM tblmain WHERE dep_id=1 ORDER BY tblmain.ref_date DESC)
ORDER BY tblmain.ref_date;
I would appreciate any feedback. After finishing this query, I plan to use this query in a form where I can choose an reference date and threshold.
Many thanks in advance!
Query to pull prior val for each record:
SELECT tblMain.ID, tblMain.ref_date, tblMain.dep_id, tblMain.val,
(SELECT TOP 1 val FROM tblMain AS Dupe
WHERE Dupe.dep_id=tblMain.dep_id AND Dupe.ref_Date < tblMain.ref_date
ORDER BY dupe.ref_date) AS PriorVal
FROM tblMain;
Now use that query to calculate percentage:
SELECT Query1.*, Abs(([PriorVal]-[val])/[PriorVal]*100) AS P
FROM Query1
WHERE (((Abs(([PriorVal]-[val])/[PriorVal]*100))>5));

Using range of cells as conditions in SQL Query

My company uses a SQL Server database.
Is it possible to use a range of cells as a condition in a SQL query if it equals ANY of those values? Can it even use date ranges on the same rows?
Reference Example:
Data Example:
Output Desired:
Question 1:
Can I reference an entire column?
SELECT ID, sum(units) FROM sales WHERE ID = any ID in Column A
Question 2:
Can I specify just a cell range?
SELECT ID, sum(units) FROM table WHERE ID = any value in A2:A10
Question 3:
Can I add a date range cell reference with the possibility that the same ID may appear more than once but have a different date range (see 747375 in sample) and return results for both ranges separately?
SELECT ID, sum(units) FROM table WHERE ID = any value in A2:A10 AND DATE >= date found in column B that is next to ID in the same row AND DATE <= date found in column C that is next to ID in the same row
You can use between as following
select
r.id,
sum(units) as units
from reference r
join data d
on r.id = d.id
where d.date between r.start and r.end
group by
r.id
Question 1: Can I reference an entire column?
Yes. A default select without a where clause will reference the entire column.
Your example SELECT ID, sum(units) FROM sales WHERE ID = any ID in Column A is not logically sound. From the select, I am presuming that you want the sum of units for each individual ID, not the sum of all the units without regard to the ID. For this, you want to use group by
select ID, sum(units) totalunits
from sales
group by ID
There is no need for a where clause because you want everything.
Question 2: Can I specify just a cell range?
Yes.
And no.
There is no direct concept of "cell range" in SQL (well, maybe top but not really). Data is stored unordered in SQL. In Excel, the cell range "A2:A10" means "whatever values just happen to be in those cells at this point in time". Often this will mean "the 2nd through 10th values entered in time", or "the first through 9th values entered in time" if there is a header row. But then later you can sort the data differently and now there is different data there. In SQL, there is no order in storage. You can specify an order for the output when you select data, but that is manually specified for each select.
However, the related concept is probably rather obvious. "A2:A10" is often going to mean "the first 9 values by date/time", or "the largest/smallest 9 values" etc.
Your example SELECT ID, sum(units) FROM table WHERE ID = any value in A2:A10 needs to change to define what values you expect to be in A2:A10. For example, if A2:A10 represents the first 9 values by date, you would do something like this: (untested)
select ID, sum(units) totalunits
from sales
where ID in (select top(9) ID
from sales
order by date
)
group by ID
This would provide the sum of units for each of the IDs that were amongst the first 9 IDs entered by date (what to do with a tie for 9th I will not go into here).
Question 3: Can I add a date range cell reference with the possibility that the same ID may appear more than once but have a different date range (see 747375 in sample) and return results for both ranges separately?
This one is difficult to understand. And it might be meaningless based on the answer to your 2nd question. However, you can setup a query that chooses the IDs you want, and in that query you can also select the min and max dates. Finally, you can use the information from that query as a subquery to get the information by ID that has the sum of units within the min/max dates and one that is the sum of units outside the min/max dates. This would require some effort and I will not at this time try to figure that out for you.

Select same account numbers in a new table

Using Teradata SQL Assistant, I want to be able to pull a table a year ahead but only the ones that would match the results in the query from the year before. Here's what I am trying to do. I pulled a table that contains information where the results in a specific column equals 0 for no. I want to pull information from 1 year ahead where the results in that column equals 1 but only include the account numbers that came when I pulled the results for the year before. Like only pull the customer account numbers for the year ahead that are the same from the year before.
Explanation: I pull the one table that has 0 in the column. From that, I want to see which of those accounts became a 1 in the table from a year ahead. The table has millions of accounts and I just have my settings for 10,000 of them so I want to see of those 10,000 in the first year that did not have the product, how many of them became 1 in the second year.
Can I do this? If so, how? I have been googling and I do not think I am explaining what I am trying to do correctly in my google query so I am coming up short with results.
Thanks for clarifying. That makes it a little simpler. I would put the second year data in a subquery and filter the main table on the first year and quantity = 0. This will give you two columns one with the first year and one with the second year. If you're only looking for this information for a single product_id you will need to add this to both WHERE clauses.
SELECT TABLE_NAME.ACCOUNT_ID, TABLE_NAME.QUANTITY AS "2019" , YEAR_TWO.QUANTITY AS "2020"
FROM TABLE_NAME
LEFT JOIN
(
SELECT *
FROM TABLE
WHERE YEAR = 2020
) YEAR_TWO ON TABLE_NAME.ACCOUNT_ID = YEAR_TWO.ACCOUNT_ID
WHERE TABLE_NAME.YEAR = 2019
AND TABLE_NAME.QUANTITY = 0
If you want just the % of accounts that are no longer 0 in the second year you could try something like this (adding up all the 1s and dividing by total count)
SELECT TABLE_NAME.YEAR, SUM(YEAR_TWO.QUANTITY) / COUNT(YEAR_TWO.QUANTITY) AS PERCENTAGE_NOT_ZERO
FROM TABLE_NAME
LEFT JOIN
(
SELECT *
FROM TABLE
WHERE YEAR = 2020
) YEAR_TWO ON TABLE_NAME.ACCOUNT_ID = YEAR_TWO.ACCOUNT_ID
WHERE TABLE_NAME.YEAR = 2019
AND TABLE_NAME.QUANTITY = 0
GROUP BY TABLE_NAME.YEAR

Power pivot ytd calculation

Ok, I have watched many videos and read all sorts and I think I am nearly there, but must be missing something. In the data model I am trying to add the ytd calc to my product_table. I don't have unique dates in the product_table in column a and also they are weekly dates. I have all data for 2018 for each week of this year in set rows of 20, incrementing by one week every 20 rows. E.g. rows 1-20 are 01/01/2018, rows 21-40 are 07/01/2018, and so on.
Whilst I say they are in set rows of 20, this is an example. Some weeks there are more or less than 20 so I can't use the row count function-
Between columns c and h I have a bunch of other categories such as customer age, country etc. so there isn't a unique identifier. Do I need one for this to work? Column i is the sales column with the numbers. What I would like is a new column which gives me a ytd number for each row of data which all has unique criteria between a and h. Week 1 ytd is not going to be any different. For the next 20 rows I want it to add week1 sales to week2 sales, effectively giving me the ytd.
I could sumproduct this easily in the data set but I don't want do that. I want to use dax to save space etc..
I have a date_table which does have unique dates in the main_date column. All my date columns are formatted as date in the data model.
I have tried:
=calculate(products[sales],datesytd(date_table[main_date]))
This simply replicates the numbers in the sales column, not giving me an ytd as required. I also tried
=calculate(sum(products[sales]) ,datesytd(date_table[main_date]))
I don't know if what I am trying to do is possible. All the youtube clips don't seem to have the same issues I am having but I think they have unique dates in their data sets.
Id love to upload the data but its work stuff on a work computer so cant really. Hope I've painted the picture quite clearly.
Resolved, after googling sumif dax, mike honey had a response that i have adapted to get what i need. I needed to add the filter and earlier functions to my equarion and it ended up like this
Calculate (sum(products[sales]),
filter (sales, sales[we_date] <=earlier(sales[we_date]),
filter (sales, sales[year] =earlier(sales[year]),
filter (sales, sales[customer] =earlier(sales[customer]))
There are three other filter sections i had to add, but this now gives me the ytd i needed.
Hope this helps anyone else

SQL: Table references

Good day. I'm having a hard time figuring out how to do this:
SELECT P.GrossSalary, S.Contribution FROM Payroll AS P, SSSChart AS S WHERE
P.GrossSalary >= S.RangeStart AND P.GrossSalary <= S.RangeEnd;
I need the corresponding contribution amount from SSSChart table where the Gross Salary is between the Start and End range.
The problem is it will work on the first found matched record from Payroll table but the searching from the SSSChart table will not start from the top again for the next Payroll record, instead, will continue the search after the found record from the previous Payroll record. I tried several SQL commands but found no luck. All the help will be appreciated. (Doing this for my payroll system practice)
Do you want to query the entire Payroll table and find the corresponding contribution value from the SSSChart table for each result? Consider trying something along the lines of:
SELECT
P.GrossSalary, S.Contribution
FROM
Payroll as P
LEFT JOIN
SSSChart as S ON P.GrossSalary >= S.RangeStart AND P.GrossSalary <= S.RangeEnd
WHERE
1;
This is assuming each GrossSalary only belongs to exactly one SSSChart range.