Option group on access form as query parameter - sql

I am working in Access 2016 and I have a from that the user can select the training type the want to run the report on. All trainings has an option value of 1, Bloodborne has an option value of 2 and so on. I want to take the value of my form and pass it into a query so it will display all employees that took that training.
My form is View February Training and contains a option group within a frame that is called FrameAllorCurrent. My query contains the training field which I am able to filter with the following Like "68" Were 68 is the training ID from the training table.
I know I have to do something in the training field of the query along the lines of
[forms]![View February Training].[FrameAllOrCurrent].Value = 2
but how do I make it so when it equals 2 it makes the training field "68" and returns all my bloodborne trainings?
SQL Query:
SELECT CompletedTrainings.RecordID
,CompletedTrainings.Employee
,CompletedTrainings.Training
,CompletedTrainings.CompletedDate
,CompletedTrainings.ExpiredDate
,EmployeeInformation.Employee
,EmployeeInformation.Active
,Trainings.TrainingID
,Trainings.[Training Name]
FROM Trainings
INNER JOIN (
EmployeeInformation INNER JOIN CompletedTrainings
ON EmployeeInformation.ID = CompletedTrainings.Employee
) ON Trainings.TrainingID = CompletedTrainings.Training
WHERE (((EmployeeInformation.Active) LIKE "-1"))
ORDER BY Trainings.[Training Name]

There are several solutions to this. But one way to do it would be:
SELECT CompletedTrainings.RecordID
,CompletedTrainings.Employee
,CompletedTrainings.Training
,CompletedTrainings.CompletedDate
,CompletedTrainings.ExpiredDate
,EmployeeInformation.Employee
,EmployeeInformation.Active
,Trainings.TrainingID
,Trainings.[Training Name]
FROM Trainings
INNER JOIN (
EmployeeInformation INNER JOIN CompletedTrainings
ON EmployeeInformation.ID = CompletedTrainings.Employee
) ON Trainings.TrainingID = CompletedTrainings.Training
WHERE EmployeeInformation.Active LIKE "-1"
AND [Training Name] =
SWITCH (
[Forms]![View February Training].[FrameAllOrCurrent] = 1, "Whatever 1 should be",
[Forms]![View February Training].[FrameAllOrCurrent] = 2, "68",
[Forms]![View February Training].[FrameAllOrCurrent] = 3, "If there's a 3... etc."
)
ORDER BY Trainings.[Training Name]
NOTE: I am uncertain what your related field is, so its listed as [Training Name], this also assumes the column is in TEXT format, based on your quotations earlier. If the data type is numeric, just remove the quotes.

Related

Optimizing Access Query with Multiple sub-queries

I have a table of data that contains baseline project information, called ADMIN_WORK. I have a separate table that contains various attributes related to each project listed in ADMIN_WORK called WR_ATTRIBUTE. The structure of WR_ATTRIBUTE is such that each project has about 300 attributes (300 rows in the table) each with a unique name associated with the project number. I need to pull approximately 15 of these attributes into a final table.
I built a query with a number of sub-queries, but it takes multiple hours to run. The code below represents pulling a single attribute (called Circuit) from WR_ATTRIBUTE for all projects.
SELECT ADMIN_WORK.WR_NO AS [WR Number],
ADMIN_WORK.PREMISE_ID AS [Premise ID],
AttributeCircuit.Circuit
FROM ADMIN_WORK INNER JOIN
(SELECT ADMIN_WORK.WR_NO AS [WR Number], WR_ATTRIBUTE.ATTRIBUTE_VALUE AS Circuit
FROM ADMIN_WORK INNER JOIN
WR_ATTRIBUTE ON ADMIN_WORK.WR_NO = WR_ATTRIBUTE.WR_NO
WHERE (((WR_ATTRIBUTE.WR_ATTRIBUTE_CODE)="Circuit") AND ((ADMIN_WORK.WR_TYPE_CODE)="ACNEM"))
) AS AttributeCircuit
ON ADMIN_WORK.WR_NO = [AttributeCircuit].[WR Number]);
My final query has about 14 more of these subqueries similarly implemented, each with a different WR_ATTRIBUTE_CODE.
My final table is generated accurately, but it is extremely slow. I am wondering if there is a better way of structuring my query.
You probably just want conditional aggregation:
SELECT w.WR_NO AS [WR Number],
w.PREMISE_ID AS [Premise ID],
a.Circuit
FROM ADMIN_WORK as INNER JOIN
(SELECT a.WR_NO AS [WR Number],
MAX(IIF(a.WR_ATTRIBUTE_CODE)="Circuit" a.ATTRIBUTE_VALUE, NULL) AS Circuit ,
. . .
FROM WR_ATTRIBUTE as a
GROUP BY WR_NO
) as a
ON w.WR_NO = a.WR_NO ;

Joining results from one query with another query

I have two queries. The first gives me a list of BusinessUnitIds along with a count for each:
SELECT [b].[BusinessUnitId], COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId])
I want to take the BusinessUnitIds in this result and join them to a second query which will retrieve the Business Unit Name associated with the BusinessUnitIds. Something like the following:
Select [c].Name, [first query result].Count from [dbo].[BusinessUnit] [c]
INNER JOIN [first query result]
WHERE [c].BusinessUnitId = [first query result].BusinessUnitId
Ultimately, what I want is a listing of Business Names, along with a count of each. I haven't been able to figure out how to do this. Can anyone help? To do both queries in a single statement would be tops. Thank you.
Exmaple:
SELECT [b].[BusinessUnitId],A.Name, COUNT([b].[BusinessUnitId]) AS bucount
FROM [dbo].[ComponentTeamBusinessUnit] [b]
LEFT JOIN NameTable as A
ON A.BusinessUnitId = b.BusinessUnitId
WHERE [b].[GlobalClientFiscalYearId] = #GlobalClientFiscalYearId
AND [b].[ComponentTeamId] IN (SELECT items FROM [dbo].[fnSplit](#ComponentTeamIds, ','))
GROUP BY [b].[BusinessUnitId],A.Name
If tables are One to One, will be neat, if one to many, you will see the result like:
id name count
1 A 5
1 B 6
And if you want to group id 1, to get:
id name count
1 A,B 11
That you need to use FOR XML PATH() together with STUFF, or STRING_SPLIT, really depends on your real case.

TSQL Show greatest Parcel# from row

I have data that looks like this.
Select distinct
x.[PropertyBasics.PK Resnet Property ID], x.filname,
c.mv_30day_value '30 Day Value As Is',
c.mv_30day_repvalue '30 Day Value Repaired',
t.parcel 'Parcel#',x. *
from
Resnet_Reporting_ops.dbo.Ops_FullExportFLATV3 as X (NOLOCK)
left join
resnet_mysql.dbo.form_tax t (nolock) on x.[PropertyBasics.PK Resnet Property ID] = t.property_id
left join
resnet_mysql.dbo.form_fm c (nolock) on t.task_id = c.task_id
where
X.[PropertyBasics.Property Basics - ResID] = 217
and x.[PropertyBasics.PK Resnet Property ID] = 1153829
How do you get this data to only show 1 record for Parcel #?
select distinct tests the ENTIRE row to see if it is unique. Just the smallest little difference in any column will make a row "distinct". The following 2 values are different, so that will cause 2 rows
741722064100000
741-722-06-41-00000
and the following 2 value pairs are different, which cause 2 more rows:
500000 800000
435000 850000
in all that combines to make 4 rows.
So, it looks like we could strip the dash from data item 2 above, and that would make it equal data item 1.
replace(t.parcel,'-','') AS [Parcel#]
But is that always true? Could there be other differences in other rows not shown here?
How do we decide between the value pairs 3. or 4. ? MAX()won't work e.g.
MAX(c.mv_30day_value), MAX(c.mv_30day_repvalue)
would produce
500000 8500000
and that combination doesn't exist in the source data
The logic required to meet the expected result isn't well defined.
Try the following:
SELECT
x.[PropertyBasics.PK Resnet Property ID]
, x.filname
, MAX(c.mv_30day_value) "30 Day Value As Is"
, MAX(c.mv_30day_repvalue) "30 Day Value Repaired"
, replace(t.parcel,'-','') "Parcel#"
-- , x.* NO WAY !!
FROM Resnet_Reporting_ops.dbo.Ops_FullExportFLATV3 AS X
LEFT JOIN resnet_mysql.dbo.form_tax t ON x.[PropertyBasics.PK Resnet Property ID] = t.property_id
LEFT JOIN resnet_mysql.dbo.form_fm c ON t.task_id = c.task_id
WHERE X.[PropertyBasics.Property Basics - ResID] = 217
AND x.[PropertyBasics.PK Resnet Property ID] = 1153829
GROUP BY
x.[PropertyBasics.PK Resnet Property ID]
, x.filname
, replace(t.parcel,'-','')
;
Note. x.* isn't feasible with GROUP BY as you need to specify the columns will define each unique row. x.* is also counter productive with "select distinct" as for each additional column of output you increase the possibility of more rows. (i.e. more columns generally = more differences = more rows). Also as mentioned doubt MAX() produces a good result here.

Calculate a sum field based on two columns

I've have an access query that I am trying to run and can't seem to get it right.
I'm already calculating a sum of hours grouped by the name and a description column. I would like the total column basically to give a sum of the hours by the name and the description column
SELECT dbo_t_SAP_AttCodes.Description, Sum(dbo_v_MES_TcActivities.Hours) AS SumOfHours,
Left([supervisor1email],InStr([supervisor1email],".")-1) AS [Supervisor First Name],
Mid([supervisor1email],InStr([supervisor1email],".")+1,
InStr([supervisor1email],"#")-InStr([supervisor1email],".")-1)
AS [Supervisor Last Name], (SELECT sum([hours]) FROM [dbo_v_MES_TcActivities]
WHERE [costctr]="106330" AND [clockin] Between DateAdd("d",-((Weekday(Date())-1)),
Date()) And Date()) AS Total_Hours
FROM dbo_v_MES_TcActivities LEFT JOIN dbo_t_SAP_AttCodes
ON dbo_v_MES_TcActivities.AttCode = dbo_t_SAP_AttCodes.Code
WHERE (((dbo_v_MES_TcActivities.AttCode) Not Like "MEAL")
AND ((dbo_v_MES_TcActivities.CostCtr) Like "106330")
AND ((dbo_v_MES_TcActivities.ClockIn) Between DateAdd("d",-((Weekday(Date())-1)),
Date()) And Date()))
GROUP BY dbo_t_SAP_AttCodes.Description, Left([supervisor1email],
InStr([supervisor1email],".")-1),
Mid([supervisor1email],InStr([supervisor1email],".")+1,
InStr([supervisor1email],"#")-InStr([supervisor1email],".")-1),
dbo_v_MES_TcActivities.Supervisor1Email
ORDER BY Mid([supervisor1email],InStr([supervisor1email],".")+1,
InStr([supervisor1email],"#")-InStr([supervisor1email],".")-1);
EDIT:
Here is what the current output looks like:
before
Here is what I would like to see:
After
Consider turning your subquery to a correlated subquery where you match the nested SELECT statement to corresponding row's name in main query without Description (only Name) grouping. The below comes out long due to Supervisor first and last name calculated expressions.
Please note: below uses table aliases with sub and main (adjust all field references accordingly):
Subquery
SELECT --...same fields/expressions as original w/ 'main' alias...,
(SELECT SUM(sub.[hours]) FROM [dbo_v_MES_TcActivities] sub
WHERE sub.[costctr]="106330"
AND sub.AttCode Not Like "MEAL"
AND sub.[clockin] Between DateAdd("d",-((Weekday(Date())-1)), Date()) And Date()
AND Left(sub.[supervisor1email], InStr(sub.[supervisor1email],".")-1) =
Left(main.[supervisor1email], InStr(main.[supervisor1email],".")-1)
AND Mid(sub.[supervisor1email], InStr(sub.[supervisor1email],".")+1,
InStr(sub.[supervisor1email],"#") - InStr(sub.[supervisor1email],".")-1) =
Mid(main.[supervisor1email], InStr(main.[supervisor1email],".")+1,
InStr(main.[supervisor1email],"#") - InStr(main.[supervisor1email],".")-1)
) AS Total_Hours
FROM dbo_v_MES_TcActivities main
LEFT JOIN dbo_t_SAP_AttCodes sap
ON main.AttCode = sap.Code
--...same WHERE and GROUPBY as original w/ 'main' and 'sap' aliases...
Derived Tables
Alternatively, turn both aggregate queries into derived tables joined into main query. In MS Access you can even save both nested SELECT statements as separate, saved queries and reference them in FROM and JOIN clause. Again, note the table aliases:
SELECT t1.Description, t1.SumOfHours, t1.[Supervisor First Name], t1.[Supervisor Last Name],
t2.TotalHours
FROM (
SELECT --...same fields/expressions as original...
FROM dbo_v_MES_TcActivities main
LEFT JOIN dbo_t_SAP_AttCodes sap
ON main.AttCode = sap.Code
--...same WHERE and GROUPBY as original...
) As t1
INNER JOIN
(
SELECT SUM(sub.[hours]),
Left(sub.[supervisor1email], InStr(sub.[supervisor1email],".")-1)
AS [Supervisor First Name],
Mid(sub.[supervisor1email], InStr(sub.[supervisor1email],".")+1,
InStr(sub.[supervisor1email],"#") - InStr(sub.[supervisor1email],".")-1)
AS [Supervisor Last Name]
FROM [dbo_v_MES_TcActivities] sub
WHERE sub.[costctr]="106330"
AND sub.AttCode Not Like "MEAL"
AND sub.[clockin] Between DateAdd("d",-((Weekday(Date())-1)), Date()) And Date()
GROUP BY
Left(sub.[supervisor1email], InStr(sub.[supervisor1email],".")-1),
Mid(sub.[supervisor1email], InStr(sub.[supervisor1email],".")+1,
InStr(sub.[supervisor1email],"#") - InStr(sub.[supervisor1email],".")-1)
) AS t2
ON t1.[Supervisor First Name] = t2.[Supervisor First Name]
AND t1.[Supervisor Last Name] = t2.[Supervisor Last Name]

SQL Reporting count of parameter in a column

I am working in SSRS 3.0 with a SQL table including the following fields:
ApptID BookedBy ConfirmedBy CancelledBy
I also have a parameter setup to select which users to filter by (matches data in the BookedBy, ConfirmedBy and CancelledBy columns) called #Scheduler (which is a multi vale parameter/array).
I need to get a count for booked, confirmed and scheduled for how many times any value in the Scheduler parameter shows up in that column.
Basically:
COUNT(BookedBy IN (#Scheduler)) AS BookedCount
Can anyone help me out with the syntax for doing this?
Try this
SELECT Count(BookedBy = #Scheduler) as [BookedCount],
Count(ConfirmedBy = #Scheduler) as [ConfirmedCount],
Count(CancelledBy = #Scheduler) as [CancelledCount]
FROM tablename
WHERE BookedBy = #Scheduler OR
ConfirmedBy = #Scheduler OR
CancelledBy = #Scheduler
NB - Not tested might contain typos
If your input is a list separated by commas you can convert that to a table. See a reference like this:
http://www.projectdmx.com/tsql/sqlarrays.aspx
For this use case I'd recommend one of the solutions that saves the result in a CTE (since you only need to convert your input once and this will be fastest)
Then you could use that table (called sTable with column name) like this:
SELECT Count(Bo.Name) as [BookedCount],
Count(Co.Name) as [ConfirmedCount],
Count(Ca.Name) as [CancelledCount]
FROM tablename
LEFT JOIN sTable Bo ON BookedBy = Bo.name
LEFT JOIN sTable Co ON ConfirmedBy = Co.name
LEFT JOIN sTable Ca ON CancelledBy = Ca.name
I guess this will work but it does not seem as nice as the others:
SELECT (SELECT COUNT(*) FROM table WHERE BookedBy in (#Scheduler)) AS [BookedCount],
(SELECT COUNT(*) FROM table WHERE ConfirmedBy in (#Scheduler)) as [ConfirmedCount],
(SELECT COUNT(*) FROM table WHERE CancelledBy in (#Scheduler)) as [CancelledCount]