Does Not Include Specified Expression as Part of Aggregate Function - ms-access

I've researched this issue but can't figure out what exactly it is that I'm doing wrong. I have the following SQL code in an Access Query.
SELECT [Age and Info Report].[Approval Status]
FROM [Age and Info Report]
GROUP BY [Age and Info Report].[Approval Status]
HAVING ((([Age and Info Report].[Approval Status])="Pending"));
I keep getting this error:
You tried to execute a query that does not include the specified
expression '[Age and Info Report].[Approval Status]="Pending" as part
of an aggregate function.
The Approval Status field has text strings that read Approved, Pending, or Rejected. I just want to return the Pending and a count of the Pending items, but I can't get past just using "Pending" as the criteria.

For simplicity, I've reduced your expression to this:
select
x
from y
group by
x
having
x = "Pending";
And the problem is it appears you'd rather have this:
select
x
, count(*) as PendingCount
from y
where
x = "Pending"
group by
x
Having is used to say thing more like
having count(*) > Q
And that would tell you which items, after grouping, were found to have occurred more than Q times in the original data.
where applies a filter to the records selected before they are aggregated. having applies a filter (which must be stated as some sort of aggregation filter, such as count() ) to the results after they've been aggregated.

Related

Using a COUNT value in an expression getting..does not include specified expression as part of an aggregate function

I am trying to display a warning if a bike station gets to over 90% full or less than 10% full. When i run this query I get "you are trying to execute query that does not include the iif statment... as part of an aggregate function.
Bike_locations table - Bicycle_id and Locations_ID
Locations table - Locations_ID, No_of_Spaces, Location_Address
SELECT Locations.Location_Address, Count(Bike_Locations.Bicycle_ID) AS CountOfBicycle_ID,
IIf(((([CountOfBicycle_ID]/[LOCATIONS]![No_Of_Spaces])*100)>90),"This Station is nearly full.
Need to move some bicycles out of here",IIf(((([CountOfBicycle_ID]/[LOCATIONS]![No_Of_Spaces])*100)
<10),"This station is nearly empty. Need to move some bicycles here","")) AS Warnings
FROM Locations INNER JOIN Bike_Locations ON Locations.[LOCATIONS_ID] = Bike_Locations.[LOCATIONS_ID]
GROUP BY Locations.Location_Address;
Anyone got a scooby
When you use a GROUP BY, you should have the exact same fields in both your SELECT and GROUP BY statements, except for the aggregate function that should only be specified in the SELECT
The aggregate function in your case is the COUNT(*)
The fields you aggregate on are:
in the SELECT : Location_Address and Warnings
in the GROUP BY : Location_Address only
The error message is telling you that you don't have the same in both statements.
2 solutions:
Remove the Warnings from the SELECT statement
Add the Warnings to the GROUP BY statement
Note that in MS Access SQL, you can't (unfortunately) use in the GROUP BY, the Aliases specified in the SELECT. So you have to copy over the whole field, which would be the long iif in your case
Edit: better solution proposal:
I would radically change your approach as you'll go no where with all those nested iff
Create the following Query and Name it (for instance) Stations_Occupation
SELECT L.Locations_ID AS ID,
L.Location_Address AS Addr,
L.No_of_Spaces AS TotSpace,
BL.cnt AS OccSpace,
ROUND((BL.cnt/L.No_of_Spaces*100),0) AS OccPourc
FROM Locations L
LEFT JOIN
(
SELECT Locations_ID, COUNT(*) AS cnt
FROM Bike_Locations
GROUP BY LOCATIONS_ID
) AS BL ON L.Locations_ID = BL.Locations_ID
This query will probably be a lot helpfull in many parts of your application, and not only here, as it calculates the occupation % of each station
Some examples:
Get all stations with >90% occupation:
SELECT Addr
FROM Stations_Occupation
WHERE OccPourc > 90
Get all stations with <10% occupation:
SELECT Addr
FROM Stations_Occupation
WHERE OccPourc < 10
Get Occupation level of a specific station:
SELECT OccPourc
FROM Stations_Occupation
WHERE ID=specific_station_ID
Get number of bikes and max on a specific station:
SELECT OccSpace & "/" & TotSpace
FROM Stations_Occupation
WHERE ID=specific_station_ID

Complex group by function for normalizing data

I have a table which has dstipv4 and pkts fields. I want to calculate STDEV of normalized pkts for each dstipv4. I write a query like this it but does not work — generating the error:
#1111 - Invalid use of group function
How to write a correct query?
SELECT dstipv4, STDEV((pkts-min(pkts))/(max(pkts)-min(pkts))) FROM flow
group by dstipv4
I'm not sure how best to explain it, but your calculation as shown requires prescience on the part of the DBMS, and the error message is the DBMS telling you that it doesn't have the requisite foresight.
I think you need to calculate the MAX and MIN values in a sub-query:
SELECT f.dstipv4, STDEV((f.pkts - m.min_pkts) / (m.max_pkts - m.min_pkts))
FROM flow AS f
JOIN (SELECT dstipv4, MIN(pkts) AS min_pkts, MAX(pkts) AS max_pkts
FROM flow
GROUP BY dstipv4
) AS m
ON f.dstipv4 = m.dstipv4
GROUP BY f.dstipv4

Refine Query Results from MySQL Database

I have the following query:
SELECT routes.route_date, time_slots.name, time_slots.openings, time_slots.appointments
FROM routes
INNER JOIN time_slots ON routes.route_id = time_slots.route_id
WHERE route_date
BETWEEN 20140109
AND 20140115
AND time_slots.openings > time_slots.appointments
ORDER BY route_date, name
This works just fine and will produce the following results:
What I want to do is only return one name per date. So the 9th, name = 1, would only have 1 result, rather than 2, as it currently does.
UPDATE: See the SQLFIDDLE for different type of solutions here: http://sqlfiddle.com/#!2/9ac65b/6
Will it solve your request if you use...
SELECT DISTINCT routes.route_date...your query... ?
It depends if you know that your rows always will have the same values, for same date/name.
Otherwise use group by...
(which I think suits your request best)
SELECT routes.route_date, time_slots.name, sum(time_slots.openings), sum(time_slots.appointments)
FROM routes
INNER JOIN time_slots ON routes.route_id = time_slots.route_id
WHERE route_date
BETWEEN 20140109
AND 20140115
AND time_slots.openings > time_slots.appointments
group by routes.route_date, time_slots.name
ORDER BY route_date, name
(i did a sum for the openings and appointments, you could do min, max, count, etc. Pick the one that fits your requirements best!)
You need to figure out which "name" you want when there are several for the same date.
Then you can group by date and select the right "name" by using an aggregate function like COUNT, MAX, etc.
I can't help you more if you don't explain your rule for picking one.

MAX Date Less Than Another Date

I am trying to determine the count of attendance for a training course between 2007-2013. I need it to pull the employees job group they were in during the time frame:
SELECT O867IA_VJOBHST.JOB_CLS_CD, O867IA_VJOBHST.DIS_NR,
Sum(IIf(emp_tng_stt_dt Between #1/1/2007# And #12/31/2011#,1,0)) AS [2007-2011],
Sum(IIf(emp_tng_stt_dt Between #1/1/2011# And #12/31/2011#,1,0)) AS 2011,
Sum(IIf(emp_tng_stt_dt Between #1/1/2012# And #12/31/2012#,1,0)) AS 2012,
Sum(IIf(emp_tng_stt_dt Between #1/1/2013# And #9/23/2013#,1,0)) AS 2013, O867IA_VJOBHST.REC_EFF_STT_DT, O867IA_VTRAING.EMP_TNG_STT_DT
FROM (O867IA_VJOBHST INNER JOIN O867IA_VTRAING ON O867IA_VJOBHST.SYS_EMP_ID_NR = O867IA_VTRAING.SYS_EMP_ID_NR) INNER JOIN O867IA_VPJOBCO ON O867IA_VJOBHST.JOB_CLS_CD = O867IA_VPJOBCO.JOB_CLS_CD
WHERE (((O867IA_VTRAING.REG_NR)="03") AND ((O867IA_VTRAING.TNG_SYS_NR)="0918") AND ((O867IA_VPJOBCO.JOB_GRP_CD)="61"))
GROUP BY O867IA_VJOBHST.JOB_CLS_CD, O867IA_VJOBHST.DIS_NR, O867IA_VJOBHST.REC_EFF_STT_DT, O867IA_VTRAING.EMP_TNG_STT_DT;
The REC_EFF_STT_DT field is the date they were recorded in their job, so I am trying to get that to be the MAX date, and it needs to be less than EMP_TNG_STT_DT which is when the training course was held. I try set it up like (((O867IA_VJOBHST.REC_EFF_STT_DT)<[O867IA_VTRAING].[EMP_TNG_STT_DT])); but it keeps giving me an error "you tried to execute a query that does not include the specified expression" whenever I add the MAX to REC EFF STT DT. I cannot find any solutions and need assistance.
If your ((MAX(O867IA_VJOBHST.REC_EFF_STT_DT) < [O867IA_VTRAING].[EMP_TNG_STT_DT])) is giving you this error, then perhaps it is also in your SELECT list, and is not just a 'Whereclause. Try removing it from yourSELECT` list.
Another suggestion is that [O867IA_VTRAING].[EMP_TNG_STT_DT] is not aggregated. You may be able to get this to work by aggregating that too. If you want the unaltered value, a FIRST() may work.

How to count unique occurences of Data in SQL

I am trying to count unique occurrences of a Client ID in the following code.
TRANSFORM Count(Research.Client_ID) AS CountOfClient_ID
SELECT Research.Treatment, Count(DCount("[Client_ID]","[Letter Status]")) AS [Total Letters Sent]
FROM Research INNER JOIN [Letter Status] ON Research.Client_ID = [Letter Status].Client_ID
GROUP BY Research.Treatment
PIVOT [Letter Status].Letter_Status;
The expression I think needs to be modified is:
Total Letters Sent: Count(DCount("[Client_ID]","[Letter Status]"))
The typical form for the DCount function is (expression, domain, *criteria*). I am pretty sure I need to specify, somehow, that the [Client_ID] should be unique in the criteria argument of the DCount function, but I don't know how. Is this possible?
If this query doesn't get what you want, please show us with sample data how it differs from what you want.
SELECT
q.Treatment,
Count(*) AS [Total Letters Sent]
FROM
[SELECT DISTINCT
Treatment,
Client_ID
FROM
Research
]. AS q
GROUP BY
q.Treatment;