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.
Related
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.
I need to figure out a way to group these properly. I have a results set that returns Incident numbers which are actually datatype string, that have revisions done. I only need the grouping of the last revision number entered. Such as the below.
INC-101
INC-101
INC-101A1
INC-101A1
INC-101A2
INC-101A2
JNC-101
JNC-101
JNC-101S1
JNC-101S1
How could I only see the highest revision number such as the following:
INC-101A2
INC-101A2
JNC-101S1
JNC-101S1
You can use GROUP BY with SUBSTRING, e.g.:
SELECT MAX(incident_no)
FROM incidents
GROUP BY SUBSTRING(incident_no, 1, 7);
Here's the SQL Fiddle.
Update
If you want all the rows belonging to the latest revision number then you can use the above query as sub-query, e.g.:
SELECT *
FROM incidents
WHERE incident_no IN (
SELECT MAX(incident_no)
FROM incidents
GROUP BY SUBSTRING(incident_no, 1, 7)
);
You could use the max-function in conjunction with group by on the "base" of an incident numner. Not sure, if it works completely as you expect, since I do not know the number system used. But maybe with some adaptions you get the results you want rather easy:
select max(incnumber)
from incidents
group by left(incnumber,7)
pry(main)> Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").last.statistics.map(&:state)
2015-09-21 20:53:54,423|65310|DEBUG|development| - Loan Load (0.9ms) SELECT `loans`.* FROM `loans` INNER JOIN `statistics` ON `statistics`.`loan_id` = `loans`.`id` WHERE `loans`.`state` IN ('started', 'pending_declined') AND (`statistics`.`state` NOT IN ('prequalified', 'conditionally_approved', '4506t_results_uploaded', 'customer_forms_uploaded', 'ready_for_etran', 'etran_verified', 'forms_to_be_verified', 'forms_verified', 'credit_memo_entered', 'loandoc_generated', 'loandoc_completed', 'loandoc_customer_received_need_signatures', 'signatures_checked_and_uploaded', 'boarded')) ORDER BY `loans`.`created_at` ASC LIMIT 1
2015-09-21 20:53:54,426|65310|DEBUG|development| - Statistic Load (0.3ms) SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97
=> ["started", "prequalified", "conditionally_approved", "customer_forms_uploaded", "ready_for_etran", "pending_declined"]
So, maybe I'm not understanding what's going on here... I'm asking SQL to find me some Loans where their Statistics do not contain certain values. In this example, I'm saying to leave out any loans with a Statistic of prequalified, but, as you can see from the print out, the Loan#statistics does have prequalified, along with several other states I'd like to leave out.
Can anyone shed some light on this? I've been fighting with it for hours, and my head is spinning at this point.
With that ActiveRecord query, you've:
First, found a set of loans
next, ordered by created_at
then, used last to find limit to 1 result, finding the oldest of the set
So, you have an instance of Loan.
Since you called #statistics on the method, I can infer that loan has_many :statistics, and you've found all statistics that holds a foreign key value that matches the instance of Loan that you found. Now you have set of statistics.
For the set of statistics, you've mapped them to the map attribute.
Since you've already joined the statistics try removing .last.statistics from your query. User map on the result set to its state. Also, consider using #includes or #select.
It because you use last.statistics. It means the result on loan object will be joined with statistics whereas you have created condition before.
Look at your last result query:
Statistic Load (0.3ms) SELECT DISTINCT `statistics`.* FROM `statistics` WHERE `statistics`.`loan_id` = 97
remove your last.statistics
Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).order(created_at: "desc").map(&:state)
or
if you want to add condition to determine some loans that you need in before map(&state)
Loan.joins(:statistics).where(state: <some states>).where.not(statistics: {state: <some other states>}).where("loans.id IN (97)").order(created_at: "desc")
You query returns product of Loan and Statistic so it still returns Loan records that have some Statistic that does not have state you specified.
If you only want Loan that has no Statistic on those states at all you probably want your SQL to be something along this line:
SELECT loans.*,
FROM loans
LEFT OUTER JOIN (
SELECT statistics.loan_id, COUNT(*) count
FROM quotes
WHERE statistics.state IN ('prequalified', 'conditionally_approved')
GROUP BY statistics.loan_id
) statistics
ON statistics.loan_id = loans.id
WHERE loans.state IN ('started', 'pending_declined')
AND statistics.count IS NULL;
My SQLfu is not what I'd be proud of so this might not be the most optimised query ever but it should get the result you expect.
You could convert that to ActiveRecord query interface but unfortunately subquery and LEFT JOIN are not really supported, at least not in the way that we going to use it will be something like this:
join_query = <<SQL
LEFT OUTER JOIN (
SELECT statistics.loan_id, COUNT(*) AS count
FROM statistics
WHERE statistics.state IN (<<state>>)
) statistics ON loans.id = statistics.loan_id
SQL
Loan
.joins(join_query)
.where(statistics: { count: null })
.where(state: <<somestate>>)
.order(created_at: :desc)
The <<SQL ... SQL is Heredoc by the way if you're not familiar with it.
I have a report in Access 2013 that prints an equipment log. There is a bunch of dates listed for each piece of equipment. I wanted to only print the newest date for each piece of equipment. I have searched the internet and this site with no luck. So any suggestions will be greatly appreciated.
My SQL statement is:
SELECT dbo_eq_location_transfer_d.equipment_id, dbo_equipment.description, dbo_eq_location_transfer_d.transaction_no, dbo_eq_location_transfer_d.job_no, dbo_jobs.description, dbo_eq_location_transfer_d.date_booked, dbo_eq_location_transfer_d.delivery_time, dbo_eq_location_transfer_d.line_no, dbo_eq_location_transfer_d.row_modified_by, dbo_eq_location_transfer_d.comment
FROM (dbo_eq_location_transfer_d INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no) INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no
ORDER BY dbo_eq_location_transfer_d.equipment_id, dbo_eq_location_transfer_d.transaction_no;
The date_booked field is the date field I am trying narrow down. I have a simple SQL query that works and I have been trying copy that into the about SQL but cannot seem to get it to mesh. It is:
SELECT [dbo_eq_location_transfer_d.equipment_no], Max(dbo_eq_location_transfer_d.date_booked) AS ["Newest Date"]
FROM dbo_eq_location_transfer_d
GROUP BY [dbo_eq_location_transfer_d.equipment_no];
In your query set the date fields criteria to:
>Now()-30
This will show any dates for the last 30 days just change 30 to the number of days you want to see.
Now that I understand your structure & data, here is what I did:
(1) Create the following query to select only the most recent 'date_booked' for each 'equipment_no'; save the query with name '23020071_A':
SELECT dbo_eq_location_transfer_d.equipment_no,
First(dbo_eq_location_transfer_d.transaction_no) AS FirstOftransaction_no,
First(dbo_eq_location_transfer_d.job_no) AS FirstOfjob_no,
First(dbo_eq_location_transfer_d.date_booked) AS FirstOfdate_booked
FROM (dbo_eq_location_transfer_d
INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no)
INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no
GROUP BY dbo_eq_location_transfer_d.equipment_no
ORDER BY First(dbo_eq_location_transfer_d.date_booked) DESC;
(2) I created the following query combining the new query with your existing query:
SELECT dbo_eq_location_transfer_d.equipment_id, dbo_equipment.description,
dbo_eq_location_transfer_d.transaction_no, dbo_eq_location_transfer_d.job_no,
dbo_jobs.description, dbo_eq_location_transfer_d.date_booked,
dbo_eq_location_transfer_d.delivery_time, dbo_eq_location_transfer_d.line_no,
dbo_eq_location_transfer_d.row_modified_by, dbo_eq_location_transfer_d.comment
FROM 23020071_A INNER JOIN ((dbo_eq_location_transfer_d
INNER JOIN dbo_jobs ON dbo_eq_location_transfer_d.job_no = dbo_jobs.job_no)
INNER JOIN dbo_equipment ON dbo_eq_location_transfer_d.equipment_no = dbo_equipment.equipment_no)
ON ([23020071_A].FirstOftransaction_no = dbo_eq_location_transfer_d.transaction_no)
AND ([23020071_A].equipment_no = dbo_eq_location_transfer_d.equipment_no)
AND ([23020071_A].FirstOfjob_no = dbo_eq_location_transfer_d.job_no)
ORDER BY dbo_eq_location_transfer_d.equipment_id, dbo_eq_location_transfer_d.transaction_no;
Now when I run the second query, it returns only the most recent row for that piece of equipment.
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.