Adding Sum into Details view for Crystal Report - sql

I am trying to update a Crystal Report with a new column. This report ("Employee Roster") looks at one table (PREH) and puts out some details, the important ones being Employee, Company, and Craft. The user specifies parameters (Company, Craft, specific Employee [optional]) and the report spits out all employees for that craft/date range and a few other details for them.
I want to add another column for their "HoursWorked" in a given craft, the details of which are found in a different table, PRTH. In PRTH there is one line for each "hours added" entry, and there may be hundreds or thousands of these for a given employee. The SQL for this would be something like:
SELECT SUM(Hours)
FROM dbo.PRTH
WHERE PRTH.Employee=%Employee
AND PRTH.Craft=%Craft
AND PRTH.Company=%Company
AND PRTH.EarnCode NOT IN ('5','6','52','60','100','103')
The main problem I'm finding is that I can't just do a simple join, as that causes a lot of row bloat. Right now the report puts out one line for each employee (grouping by craft) - if I join the table I need, then it makes a LOT of lines for each employee. I want to add just the summary of Hours, based off the current employee that's being looked at in the Details section. I can do what I want in SQL but am not sure how to pass that on in Crystal Reports, ultimately trying to use results of the main report as parameters in this second search.
Any help is greatly appreciated, thank you.
SAMPLE OUTPUT FOR CURRENT REPORT (Parameters=Company 1, Craft=46T)
EE# SortName FullName Co Craft
1553 BOBJONES Jones, Bob 1 46T
1672 RACHELJONES Jones, Rachel 1 46T
2007 TANYAADAMS Adams, Tanya 1 46T
In the above output, I'd be trying to add a new Column "TotalHours". For the first line, I'd expect it to run the SQL statement using Bob Jones' EE for "%Employee", his Craft for "%Craft", and his Company for "%Company".

It sounds like what you're trying to achieve is just this:
SELECT [EE#], SortName, FullName, Co, Craft,
(SELECT SUM(Hours)
FROM dbo.PRTH
WHERE PRTH.Employee=e.Employee
AND PRTH.Craft=e.Craft
AND PRTH.Company=e.Company
AND PRTH.EarnCode NOT IN ('5','6','52','60','100','103')) AS TotalHours
FROM TableWithEmployees AS e
WHERE PRTH.Employee=%Employee
AND PRTH.Craft=%Craft
AND PRTH.Company=%Company;
Is that what you mean?

Related

SQL "group the rows" - (confusing exam question)

I got one question for SQL query (sql server) for which I am very confused what they want to me display in the first place. This is one exam question, so I do not believe it's a mistake and unfortunately I cannot ask for clarification.
Question:
"Write a query that has the following columns:
Transaction ID, Stock type.
Group the rows according to the portfolio."
My current query will be:
select p.prfid 'Portfolio', t.trdnbr 'Transaction ID', s.instype 'Stock Type'
from transaction t, stock s, portfolio p
where t.insaddr = s.insaddr
and t.prfnbr = p.prfnbr
One portfolio can have multiple transactions, but I am confused because they are not looking for number of transactions per portfolio (in which way "group by" will have total sense), so I am not sure in which way I should group them (except of simple sorting).
Also I was wondered if they expected me to write portfolio name in the where clause in order to group similar transactions... I don't know I am very confused.
Please help at least in which way you think they want me to present the result.
My current sample output for better view of data (it DOES NOT mean it should look like that))
Portfolio Transaction ID Stock Type
Cash 1001 Deposit
Cash 1002 Currency
Crypto 1003 Stock
Thanks

MS Access - Take hourly rate and employee name from another table and multiply by time taken

I am not too sure how to approach this method and was wondering if anyone could assist me.
Basically, I have a table (tblLogInspection) where the data is input via the user from separate form (frmAddInspectionRecord). I have used vba so that upon a button click all data that has been input will transfer to the table.
What I have is another table (tblemployeedetails), i.e. their name and hourly rate. On (frmAddInspectionRecord) there is a combo box that is quiered from (tblemployeedetails) where the user can select which employee has conducted the work. Upon this data being added to (tblLogInspection) I would like a column which takes the hourly rate of the employee that has conducted the work from (tblemployeedetails) and multiply it by the TIMETAKEN column in (tblLogInspection).
I hope that I have explained this with enough detail. If anyone could help guide me in the right direction I would be so grateful!
I think, the most straightforward solution to this would be a query (as already suggested by Stewart Ross)
Imagine your tables are set up like this:
tblemployeedetails:
Employee_ID | Employee_Name | HourlyRate
tblLogInspection:
Inspection_ID | Employee_ID | TimeTaken
Now, set up a query with a calculated field:
SELECT q2.Inspection_ID AND q2.TimeTaken * q1.HourlyRate
FROM tblemployeedetails AS q1
INNER JOIN tblLogInspection AS q2 ON q1.Employee_ID = q2.Employee_ID

Using a query for Single field in Access Report

I am new to access. I have a report with a query(Q1) as its data source. Is it possible to use another query(Q2) only for one field in the same report?
My main query is:
SELECT PersonTotalHours.*, Person.*
FROM PersonTotalHours
INNER JOIN Person
ON PersonTotalHours.LastName = Person.LastName;
My report's structure is like this:
Report header
_____________
Page header
_____________
Lastname header
_____________
report details
_____________
Lastname Footer
_____________
PageFooter
As you can see, in the report I group my data using the Lastname column then I show details about each peron for current year.
I need to show short form of data about former years of each person in the Last name header (somewhere before the detailed data).
Second query is like this:
SELECT PersonTotalHours.MA, PersonTotalHours.Year, Sum(PersonTotalHours.Hours) AS Sum
FROM PersonTotalHours
GROUP BY PersonTotalHours.MA, PersonTotalHours.Year
I use this for short form of data.
Important point is that the number of rows can be different. Person A might have 0 previous years and another person has more than 5.
How is it possible to use the second query for parts of report data?
I solve the problem using a subreport.
http://www.simply-access.com/Multiple-Queries-in-Report.html

Access/SQL Select Query - Return "Most Like" Value Only

We have a chargeback process in an AccessDB where Departments must approve the expenses entered by another department. We only want a single 'default' approver, but the way the data has been set-up and the query we currently use to fill in the approver returns multiple results.
In the tUserSec table, for example, we have two columns. Name(UserIDX) and UserCode
User1 - 550*
User2 - 55003*
The idea here being that User1 is the Director and so is a 'catchall' for everything in this department, while User2 is a Manager and is specifically assigned to a narrower division. Departments are always 7 characters total.
Say the Department is 5500309, the idea is that User2 should populate as the approver since their code is most closely matched to the Department ID. However, using the "Like" criteria returns both users and the form appears to select one of the two users at random with no rhyme or reason that I can determine. It always selects User1 for 5500309 but always selects User2 for 5500301, despite there being no further delineation - but ideally User1 shouldn't be populating at all unless no one else matches closer.
Below is a simplified version of the SQL, I cut out some other stuff that muddies the situation:
SELECT TDepts.Dept, TDepts.DDescr, tUserSec.UserIDX
FROM tUserSec, TDepts
WHERE (((TDepts.Dept) Like [usercode] & "*"));
How can I change this up so that I only pull in the UserID who is most like the usercode? I tried to figure out a way to pull in the UserID based on the length or max of the usercode, etc. but I wasn't able to find a way that worked. It's a safe assumption that if two users have usercodes that are "like" the department that the usercode that is longest is the one we want.
(This is my first question on here and a struggled with how to best explain this issue. Please be gentle :) )
First, I have to say that the main problem here is when a developer thought that they would be clever and build a lot of logic into the department and user IDs. Hiding this sort of information within a column is a big source of headaches in general (as you're just starting to see).
I don't develop with Access, so I'm not certain of the syntax, but hopefully you'll get the general idea. Please let me know if the syntax needs to be tweaked for future users who find this question:
SELECT
D.Dept,
D.DDescr,
U.UserIDX
FROM
TDepts D
LEFT OUTER JOIN
(
SELECT
SQ_D.Dept,
MAX(LEN(SQ_U.usercode)) AS max_len_usercode
FROM
TDepts SQ_D
INNER JOIN tUserSec SQ_U ON SQ_D.Dept LIKE SQ_U.usercode & "*"
GROUP BY
SQ_D.Dept
) SQ ON SQ_D.Dept = D.Dept
LEFT OUTER JOIN tUserSec U ON
D.Dept LIKE U.usercode & "*" AND
LEN(U.usercode) = SQ.max_len_usercode
The query gets a list of all of the departments along with the length of the longest usercode that matches for that department. Then it uses that to determine which user matches for the "most like" the department.

How to concatenate multiple record data into one record?

A picture is worth a thousand words, so I'll show you what I'm trying to accomplish first:
This is a report representing a schedule over the month of September.
The data is obtained from three tables: Employees, Employees_Shifts, and Shifts.
The Report's RecordSource property uses the following query to get the names:
SELECT DISTINCT
Employees.Employee_ID, Employees.Last_Name, Employees.First_Name
FROM
Shifts
INNER JOIN
(Employees
INNER JOIN
Employees_Shifts ON Employees.Employee_ID = Employees_Shifts.Employee_ID)
ON Shifts.Shift_ID = Employees_Shifts.Shift_ID
WHERE
(((Shifts.Schedule_ID) = 1))
ORDER BY
Employees.Last_Name;
So now I'm at the really tricky part where I need to populate all the textboxes with the appropriate data. Each textbox is supposed to hold one letter: A,B,C,D, etc.
Each of these is a letter "designation" assigned to any given Shift. You can have multiple shifts happening at the same time but in different locations. FYI, notice the "Part 1" in the header. I intend to make a second report that goes more into detail on each shift which you can lookup the letter designation for any given day. But that's not pertinent to this particular problem.
I need to somehow query the database for the "designation" field in the Shifts table so that I can assign all the letters: A,B,C,D, etc. into the appropriate boxes.
For instance the output of such a query maybe looks like this:
Allen Nelli 3A,7B,10A,13A,14B,17B,19C,21A
Barlow_Steeves Donna 1A,3B,7A,13B,18A,23A,25A
Beno Wayne 1B,7B,8A,10A,14B,15C
The number/letter combination would represent day and designation together so that I can somehow assign the right letter into the appropriate textbox.
I don't even know if this is at all possible using SQL. I tried tinkering with this query:
SELECT distinct
Employees.Employee_ID, Employees.Last_Name, Employees.First_Name,
Day(Shifts.Start_Date_Time) & Shifts.Designation AS Expr1
FROM
Shifts
INNER JOIN
(Employees
INNER JOIN
Employees_Shifts ON Employees.Employee_ID = Employees_Shifts.Employee_ID)
ON Shifts.Shift_ID = Employees_Shifts.Shift_ID
WHERE
(((Shifts.Schedule_ID) = 1));
However, this gives me the following output:
8 Allen Nelli 10A
8 Allen Nelli 13A
8 Allen Nelli 14B
etc.
I don't want every employee showing up in the report multiple times like that. That's why I used the DISTINCT operator in the original query.
Surely there is a way to query this database so that I can assign the appropriate letter in each textbox using its ControlSource property? Or even just doing a separate query and assign the letter to the Value property of each textbox using vba code?
Any assistance/direction would be appreciated.
I think it'll be beneficial for you to create a sub query that aggregates the shift designations based on the employeeid. Do an inner join on this sub query with the employee table. Once you have the designations aggregated, you can simply use the aggregated designations instead of "Shifts.Designation". You may also need to do a group by.