Multiple joins to create a cross tab - sql

I have two queries I want to join so I can get the percentages from each department of completed work orders but not sure how to go about it. I know I want a join and a crosstab query so I can display the results in a report.
The first query calculates the numerator,
SELECT
Count(MaximoReport.WorkOrder) AS CountOfWorkOrder,
MaximoReport.[Assigned Owner Group]
FROM MaximoReport
WHERE (
((MaximoReport.WorkType) In ("PMINS","PMOR","PMPDM","PMREG","PMRT"))
AND ((MaximoReport.Status) Like "*COMP")
AND ((MaximoReport.[Target Start])>=DateAdd("h",-1,[Enter the start date])
AND (MaximoReport.[Target Start])<DateAdd("h",23,[Enter the end date]))
AND ((MaximoReport.ActualLaborHours)<>"00:00")
AND ((MaximoReport.ActualStartDate)>=DateAdd("h",-11.8,[Enter the start date])
AND (MaximoReport.ActualStartDate)<DateAdd("h",23,[Enter the end date]))
)
GROUP BY MaximoReport.[Assigned Owner Group];
While the second query calculates the denominator:
SELECT
Count(MaximoReport.WorkOrder) AS CountOfWorkOrder,
MaximoReport.[Assigned Owner Group]
FROM MaximoReport
WHERE (
((MaximoReport.WorkType) In ("PMINS","PMOR","PMPDM","PMREG","PMRT"))
AND ((MaximoReport.Status)<>"CAN")
AND ((MaximoReport.[Target Start])>=DateAdd("h",-11.8,[Enter the start date])
AND (MaximoReport.[Target Start])<DateAdd("h",23,[Enter the end date])))
GROUP BY MaximoReport.[Assigned Owner Group];
Please advise how I can join the two queries to get the percentages of the departments and then do a crosstab query.
If there is a better way of doing this please also let me know.

Related

How to add 2nd price column in SQL when info is normally stored on 2 separate rows

I currently have a very simple SQL script, which provides the sell price for a special customer of ours, who gets Priceline "J". I'd like to add a column of Retail pricing as well for them to reference, which is normally Priceline "R". My query currently looks like this:
SELECT RS_PCL.SKU,
RS_PCL.SKU_DESC,
RS_PCL.PACKAGE,
RS_PCL.PRICE AS [Sell Price],
RS_PCL.STD AS [Start Date],
RS_PCL.END AS [End Date]
FROM RS_PCL
WHERE RS_PCL.PRICELINE = "J"
Would anyone be able to help me figure out how I could add the "R" price line as another column instead of separate rows?
I can add WHERE RS_PCL.PRICELINE IN ("J","R") but it would create a separate row for each Retail price, instead of in the column next to it. I've seen examples of a separate SELECT CASE WHEN, but not sure exactly how the syntax works.
The prices are always going to have the same start date, so it would just need to join where the SKU matches and the Start Date matches.
NOTE : IM sorry I accidentally edited your answer, not my question...
Revised: Running into errors with this code still, saying "Your query does not include the specified expression 'GL Type' as part of an aggregate function" or would say each field that isn't included in the group by clause
SELECT RS_PCL.[GL Type],
RS_PCL.SKU,
RS_PCL.[SKU Desc],
RS_PCL.Supplier,
RS_PCL.[Case UPC],
RS_PCL.[Pack UPC],
RS_PCL.[Unit UPC],
RS_PCL.PDCN,
RS_PCL.Package,
RS_PCL.[Price Start Date],
RS_PCL.[Price End Date],
Iif( RS_PCL.PRICELINE = "J" , RS_PCL.Price , Null) AS [Sell Price],
Iif( RS_PCL.PRICELINE = "R" , RS_PCL.Price , Null) AS [Retail Price],
RS_PCL.Cost,
RS_PCL.Tax,
RS_PCL.Freight
FROM RS_PCL
WHERE (RS_PCL.PRICELINE IN ("J","R"))
Tested the Self Join query listed below, I keep getting a "Syntax Error in FROM Clause" with this query.
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN SELECT (RS_PCL.SKU, RS_PCL.[Price Start Date], RS_PCL.Price AS R_PRICE FROM RS_PCL WHERE RS_PCL.PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.[Price Start Date] = R.[Price Start Date]
WHERE RS_PCL.Priceline = "J"
SELECT CASE does not work in Access query. Use IIf() or Switch() or Choose().
Perhaps a CROSSTAB query or emulate CROSSTAB with expressions to create fields. Presuming, as indicated in question title, there is one "J" and one "R" record for each data combination:
SELECT SKU, SKU_DESC, PACKAGE, STD, END,
Max(IIf(PRICELINE = "J", PRICE, Null)) AS J,
Max(IIf(PRICELINE = "R", PRICE, Null)) AS R
FROM RS_PCL
GROUP BY SKU, SKU_DESC, PACKAGE, STD, END
Or a self-join, assuming only fields needed as unique identifier are SKU and STD:
SELECT J.*, R.R_PRICE FROM RS_PCL AS J
INNER JOIN (SELECT SKU, STD, PRICE AS R_PRICE FROM RS_PCL WHERE PRICELINE = "R") AS R
ON J.SKU = R.SKU AND J.STD = R.STD
WHERE PRICELINE = "J";
This would be useful on a report but useless for a data entry form.
Yet another approach would use DLookup() domain aggregate function. Domain aggregate function can cause slow performance in query or form but the dataset would be editable.

Getting the wrong Count result in ms access

I have written an SQL query to try and get some information on a group of trees by forest type. However, when I run this query, the Count(T_Plots.ID_plot) AS [Plots/Forest Type], returns the same numbers as the Count(T_Trees.ID_Tree) AS [Trees/Forest Type]. These numbers are way too high, since the entire T_Plots table only has 175 records, while in the results table it returns outcomes as high as 4290.
What did I overlook that is causing these wrong numbers, and how do I get the correct number of plots per forest type?
SELECT
T_Plots.Forest_type,
Count(T_Plots.ID_plot) AS [Plots/Forest Type],
Count(T_Trees.ID_Tree) AS [Trees/Forest Type],
[Trees/Forest Type]/[Plots/Forest Type]*10 AS [Trees/Ha],
Avg([T_Trees.DBH (cm)])/100*Avg([T_Trees.Height (m)])*0.7*[Trees/Ha] AS [Volume (m3)/Ha],
3.142*(((Avg([T_Trees.DBH (cm)])/2)^2)/100)*[Trees/Ha] AS [BA (m2)/Ha]
FROM T_Plots INNER JOIN T_Trees
ON T_Plots.ID_plot = T_Trees.ID_plot
GROUP BY T_Plots.Forest_type
Images:T_Plots T_Trees Results
I think a DISTINCT might solve your problem. Try:
SELECT
T_Plots.Forest_type,
Count(Distinct T_Plots.ID_plot) AS [Plots/Forest Type],
Count(Distinct T_Trees.ID_Tree) AS [Trees/Forest Type],
[Trees/Forest Type]/[Plots/Forest Type]*10 AS [Trees/Ha],
Avg([T_Trees.DBH (cm)])/100*Avg([T_Trees.Height (m)])*0.7*[Trees/Ha] AS [Volume (m3)/Ha],
3.142*(((Avg([T_Trees.DBH (cm)])/2)^2)/100)*[Trees/Ha] AS [BA (m2)/Ha]
FROM T_Plots INNER JOIN T_Trees
ON T_Plots.ID_plot = T_Trees.ID_plot
GROUP BY T_Plots.Forest_type

How do I consolidate multiple entries into a new value in microsoft access query?

I am trying to aggregate the Total Sum of [Award] and Count of [Counter] for different [PO Types]. Is there a way to group all the existing PO Types into one value "SRM" within the same query?
The end result I want is one record: SRM | $37,823,372.89 | 1732
Here is the current SQL:
SELECT tblSRMECC.[PO Type], Sum(tblSRMECC.Award) AS SumOfAward, Count(tblSRMECC.[Counter (PO)]) AS
[CountOfCounter (PO)]
FROM tblSRMECC
GROUP BY [PO Type]
HAVING (((tblSRMECC.[PO Type])<>"AutoPO" And (tblSRMECC.[PO Type])<>"Fixed Price Catalog"));
One way of doing this is to amend your existing query to add a UNION that does the subtotal. Something like this as your SQL:
SELECT 0 AS DataSortOrder, tblSRMECC.[PO Type], Sum(tblSRMECC.Award) AS SumOfAward, Count(tblSRMECC.[Counter (PO)]) AS
[CountOfCounter (PO)]
FROM tblSRMECC
GROUP BY [PO Type]
HAVING (((tblSRMECC.[PO Type])<>"AutoPO" And (tblSRMECC.[PO Type])<>"Fixed Price Catalog"))
UNION SELECT 1,"SRM",Sum(tblSRMECC.Award), Count(tblSRMECC.[Counter (PO)])
FROM tblSRMECC
HAVING (((tblSRMECC.[PO Type])<>"AutoPO" And (tblSRMECC.[PO Type])<>"Fixed Price Catalog"))
ORDER BY 1,2
The extra column that I have added, DataSortOrder, is just to make sure that the total appears after the individual totals.
If you only want to show the overall total, then you can just use the part of the query that I added:
SELECT "SRM",Sum(tblSRMECC.Award), Count(tblSRMECC.[Counter (PO)])
FROM tblSRMECC
HAVING (((tblSRMECC.[PO Type])<>"AutoPO" And (tblSRMECC.[PO Type])<>"Fixed Price Catalog"))
Regards,

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]

Access Pivot Query

I want to create a crosstab query where the pivot is a field with natural numbers (delayed days of a document) but I want to group them (those documents delayed less than 1 week, then those delayed less than two weeks, and then the rest of documents) but I try and I only have those whose delayed days are just 1 week and no less and so on. This is my code:
TRANSFORM Count(BlueCielo.[Document Number]) AS [CuentaDeDocument Number1]
SELECT Documentos.[Disciplina Interna], BlueCielo.[Client Response Return Status], Count(BlueCielo.[Document Number]) AS [CuentaDeDocument Number]
FROM BlueCielo INNER JOIN Documentos ON BlueCielo.[Document Number] = Documentos.[Numero Documento Cliente]
WHERE (((Documentos.[Documento Interno])="N"))
GROUP BY Documentos.[Disciplina Interna], BlueCielo.[Client Response Return Status]
ORDER BY Documentos.[Disciplina Interna], BlueCielo.[Client Response Return Status]
PIVOT BlueCielo.[Delayed Days] in (0,7,14,21);
the part that I do not know how to implement is just the last paragraph:
PIVOT BlueCielo.[Delayed Days] in (0,7,14,21);
(BlueCielo is my table and [Delayed Days] is the field with the data).
When I try with
PIVOT BlueCielo.[Delayed Days] in (0,>7,>14,<14);
it gives me an error.
Can anyone help me? Thanks a lot!!
I have try with this and I have solve the problem!
PIVOT IIf([Delayed Days]<1,"0 dias",IIf([Delayed Days]<7,"<1 wek",IIf([Delayed Days]<14,"<2 weeks",IIf([Delayed Days]<21,"<3 weeks",">3 weeks"))));