Average score for a given name within the current month - sql

I have a table data set of customer service reps score per call for the current year and I'm trying to build a query to calculate the average score for a given name within a given month
Something like calculating the average score for Matt's calls for the month of January.
I've been trying but I'm a begginer at SQL so I'm having trouble.
So far I've got this:
Select avg("general score") as General_Score, avg("Re_score") as Re_score
from Voc2019
Where [Name] ="Matt"
This gives me a error type mismatch
Would greatly appreciate any help you can provide to me.
UPDATE:
the code now works but While this does work I still need to order by a given date, but I I want to use this sql string to retrieve the average for a month specified varying on the month I want from excel but it's not returning any results
For instance I want Avg score for Matt in January
Currently I got
Select avg([general score]) as general_score, ("Re_score") as Re_score
from Voc2019
Where [Name] ="Matt" and Score_Date = Month(2)

The main issue with your code is that you are using a string ("general score") when attempting to reference a field (this is likely producing the type mismatch error).
You haven't indicated the field in your table that contains the date for each record, and so selecting the appropriate set of records for a given month is impossible without this information.
However, to correct your current code, I would suggest the following:
select avg(voc2019.[general score]) as General_Score, avg(voc2019.re_score) as Re_score
from voc2019
where voc2019.name = "Matt"
If you were to identify the field containing the date for each record, you could calculate an average per month using something like:
select
dateserial(year(voc2019.date), month(voc2019.date), 1) as [Month],
avg(voc2019.[general score]) as General_Score,
avg(voc2019.re_score) as Re_score
from
voc2019
where
voc2019.name = "Matt"
group by
dateserial(year(voc2019.date), month(voc2019.date), 1)
The above assumes that your table voc2019 contains a field called date dating each record.
EDIT:
Since your date is actually stored as a Text field rather than a Date field, you can use the DateValue function to parse the text content into a date value.
Hence, to obtain the average score for Matt in January, you might use something like the following:
select
avg(voc2019.[general score]) as General_Score,
avg(voc2019.re_score) as Re_score
from
voc2019
where
voc2019.name = "Matt" and
month(datevalue(voc2019.date)) = 1 and
year(datevalue(voc2019.date)) = 2019
Alternatively, since your date is stored as text, you could use the like operator to match only dates in January, e.g.:
select
avg(voc2019.[general score]) as General_Score,
avg(voc2019.re_score) as Re_score
from
voc2019
where
voc2019.name = "Matt" and voc2019.date like "##-01-2019"

I am way more familiar with Oracle SQL syntax, but pretty sure the problem is with some simple MS Access syntax. Your literal string "Matt" which should be single-quoted as in 'Matt' and the square brackets are used to enclose a column identifier only when it contains a space.
Try:
Select avg([general score]) as General_Score, avg(Re_score) as Re_score
from Voc2019
Where Name = 'Matt'

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 and manipulate SQL data, DISTINCT and SUM?

Im trying to make a small report for myself to see how my much time I get inputed in my system every day.
The goal is to have my SQL to sum up the name, Total time worked and Total NG product found for one specific day.
In this order:
1.) Sort out my data for a specific 'date'. I.E 2016-06-03
2.) Present a DISTINCT value for 'operators'
3.) SUM() all time registered at this 'date' and by this 'operator' under 'total_working_time_h'
4.) SUM() all no_of_defects registered at this 'date' and by this 'operator' under 'no_of_defects'
date, operator, total_working_time_h, no_of_defects
Currently I get the data I want by using the Query below. But now I need both the DISTINCT value of the operator and the SUM of the information. Can I use sub-queries for this or should it be done by a loop? Any other hints where I can learn more about how to solve this?
If i run the DISTINCT function I don't get the opportunity to sum my data the way I try.
SELECT date, operator, total_working_time_h, no_of_defects FROM {$table_work_hours} WHERE date = '2016-06-03' "
Without knowing the table structure or contents, the following query is only a good guess. The bits to notice and work with are sum() and GROUP BY. Actually syntax will vary a bit depending on what RDBMS you are using.
SELECT
date
,operator
,SUM(total_working_time_h) AS total_working_time_h
,SUM(no_of_defects) AS no_of_defects
FROM {$table_work_hours}
WHERE date = '2016-06-03'
GROUP BY
date
,operator
(Take out the WHERE clause or replace it with a range of dates to get results per operator per date.)
I'm not sure why you are trying to do DISTINCT. You want to know the data, no of hours, etc for a specific date.
do this....
Select Date, Operator, 'SumWorkHrs'=sum(total_working_time_h),
'SumDefects'=sum(no_ofDefects) from {$table_work_hours}
Where date='2016-06-03'
Try this:
SELECT SUM(total_working_time) as total_working_time,
SUM(no_of_defects) as no_of_defects ,
DISTINCT(operator) AS operator FROM {$table_work_hours} WHERE
date = '2016-06-03'

Retrieving how many transactions were made on a date in SQL?

I have a table named Sales and a column within it named Date. I'm simply trying to find how many sales were made on a specific date. My intuition was to use something like this:
SELECT COUNT(Date) FROM Sales WHERE Date='2015-04-04'
this should count all sales that were made on that date, but that returns 0. What am I doing wrong?
While it is difficult to be precise without table definitions or an indication of what RDBMS you are using, it is likely that Date is a time/date stamp, and that the result you want would be obtained either by looking for a range from the beginning of the day to the end of the day in your WHERE clause, or by truncating Date down to a date without the time before comparing it to a date.
Try the below once.
select count(*) from <t.n> where date like '2015-04-04%';
When you want to find the count of rows based on a field (Date) You need to Group By over it like this:
SELECT Date, COUNT(*)
FROM Sales
GROUP BY Date
Now you have all count of rows for each Date.
Type and Value of Date is important in the result of the above query.
For example in SQL Server your best try is to convert a DateTime field to varchar and then check it as the result of CONVERT like this:
SELECT COUNT(*)
FROM Sales
WHERE CONVERT(VARCHAR, Date, 111) = '2015/04/04'

Having trouble using Partition() in Access

I have a table with the fields: resourceID,work_date,stringValue
I'm trying to build an Access query that will show a count of how many different resourceID numbers with a given stringValue occur in each week over a given date range. Using partition() seems to be the simplest approach, however, when I use the following query:
select partition([work_date],#6/6/2011#,#9/4/2011#,7),stringValue,
count(resourceID) from
(select distinct resourceID,work_date,stringValue from myTable) as subQuery
group by partition([work_date],#6/6/2011#,#9/4/2011#,7), stringValue
then I have two problems:
-My dates end up formatted as integers, e.g.:
:40699
40700:40706
40784:40790
whereas I want them to appear as, e.g., 6/6/2011:6/12/2011 (I also don't want the :40699 value)
-resourceID gets counted more than once per week if it appears on more than one weekday; I just want it to be counted once for each stringValue if it appears at all that week. I thought the distinct qualifier would accomplish this but it didn't.
EDIT: I've solved the excess resourceID count by putting the partition in a subquery as follows:
select datePartition,stringValue,count(ID)
from (select partition() as datePartition, stringValue, ID
from (select distinct stringvalue,ID,work_date))
group by datePartition,stringvalue
and then pulling count(ID) from that subquery. Still can't figure out the date formatting, though.
I see 2 solutions, but I see no reason for using Partition() here !
Solution 1: use SELECT Format([DateFact];"ww-yyyy") as weekOfYear will return the week number and year: fine for grouping by week, displaying the week number.
Solution 2: use SELECT [DateFact]-Weekday([datefact]+1) as weekStarting will return first day of the week as a nicely formatted date: fine for grouping by week, displaying the week starting day.
To get rid of the range which ends with 40699, try revising the subquery piece. Add a WHERE condition to limit rows to work_date values >= #6/6/2011#
SELECT DISTINCT resourceID, work_date, stringValue
FROM myTable
WHERE work_date >= #6/6/2011#;
I'm not clear about your description regarding the duplicate rows from the SELECT DISTINCT. One possibility could be that at least some of your work_date values contain different time values from the same date. So two rows with the same resourceID and stringValue, but work_date values of #6/6/2011 01:00 AM# and #6/6/2011 02:00 AM#, would legitimately qualify as distinct.
If that's not the explanation, clarify your question by showing us a smallish set of data from myTable, and the resultset of that data which illustrates how you want the data evaluated.
AFAICT, the issue about Partition() presenting your date ranges as whole numbers is unavoidable. According to the help topic, Partition() expects whole numbers for its parameters. Apparently it's willing to accept your Date/Time values by casting them to whole numbers. But it's not willing/able to transform them back to date strings. You would have to transform them back yourself. A user-defined function could do it when called from a query.
Public Function WholeNumRange2Date(ByVal pRange As String)
Const cstrFmt As String = "m/d/yyyy"
Dim varPieces As Variant
varPieces = Split(pRange, ":")
WholeNumRange2Date = Format(CDate(varPieces(0)), cstrFmt) & _
":" & Format(CDate(varPieces(1)), cstrFmt)
End Function
An example from the Immediate Window which uses that function ...
? WholeNumRange2Date("40700:40706")
6/6/2011:6/12/2011