Implementing nesting query rather than sub-query - sql

I have a MS-Access query that interprets dates and provides an appropriate status for given projects. However, this query provides data on only one division at a time. I am trying to eliminate the sub-query (highlighted in red below) so I can more easily repurpose the query for other division reports.
Below is the sub-query, named qryProjectStatusDPLphase1:
SELECT tblProject_HIF_FCF_CBH.HifFcfCbh
, tblProject_HIF_FCF_CBH.ProjectNum
, tblProject_HIF_FCF_CBH.Stat_CondCommitDt AS CondCommit
, tblProject_HIF_FCF_CBH.Stat_FirmCommitDt AS FirmCommit
, tblProject_HIF_FCF_CBH.Stat_FundAgtRecdDt AS FundAgt
, tblProject_HIF_FCF_CBH.Stat_InDisbursemtDt AS Disbursemt
, tblProject_HIF_FCF_CBH.Stat_ServicingDt AS Servicing
FROM tblProject_HIF_FCF_CBH
WHERE (tblProject_HIF_FCF_CBH.HifFcfCbh) Like "FCF";
The problem I run into is that when I insert the red subquery directly into the larger operation, Access still insists on finding the subquery. So when I forceably remove the stand-alone subquery from Access entirely, I get an error, "The Microsolft Access database engine cannot find the input table or query 'qryProjectStatusDPLphase1'..."
In an effort to identify the problem, I built up the query by adding one piece at a time. When I run the red subquery all by itself, I get no errors. When I run the red + blue sections of the query, again I get no errors. But when I run red + blue + teal sections, then I get the error. My suspicion is that there is something wrong with the way the tables are joined, that prevents red + blue + teal working together properly.
Unfortunately I've spent days on this and can't seem to crack the code, so I was hoping for some wisdom from the cloud.

You are getting the error because you aliased the inner qryProjectStatusDPLphase1 query, and you are trying to call it again in the outer query. Unfortunately, it is out of scope for the outer query, so it won't work.
If you don't want to save qryProjectStatusDPLphase1 as an Access query, you can simply paste the query's sql code into parentheses for the INNER JOIN:
...
FROM(SELECT tblProject_HIF_FCF_CBH.HifFcfCbh
, tblProject_HIF_FCF_CBH.ProjectNum
, tblProject_HIF_FCF_CBH.Stat_CondCommitDt AS CondCommit
, tblProject_HIF_FCF_CBH.Stat_FirmCommitDt AS FirmCommit
, tblProject_HIF_FCF_CBH.Stat_FundAgtRecdDt AS FundAgt
, tblProject_HIF_FCF_CBH.Stat_InDisbursemtDt AS Disbursemt
, tblProject_HIF_FCF_CBH.Stat_ServicingDt AS Servicing
FROM tblProject_HIF_FCF_CBH
WHERE (tblProject_HIF_FCF_CBH.HifFcfCbh) Like "FCF"
) AS qryProjectStatusDPLphase1, zProjectStatusDPL
)as t
INNER JOIN (SELECT tblProject_HIF_FCF_CBH.HifFcfCbh
, tblProject_HIF_FCF_CBH.ProjectNum
, tblProject_HIF_FCF_CBH.Stat_CondCommitDt AS CondCommit
, tblProject_HIF_FCF_CBH.Stat_FirmCommitDt AS FirmCommit
, tblProject_HIF_FCF_CBH.Stat_FundAgtRecdDt AS FundAgt
, tblProject_HIF_FCF_CBH.Stat_InDisbursemtDt AS Disbursemt
, tblProject_HIF_FCF_CBH.Stat_ServicingDt AS Servicing
FROM tblProject_HIF_FCF_CBH
WHERE (tblProject_HIF_FCF_CBH.HifFcfCbh) Like "FCF") AS a
...

Looking at your screen-shot, you're still trying to join the nested query t to the subquery qryProjectStatusDPLphase1:
AS t
INNER JOIN qryProjectStatusDPLphase1 As a
ON t.ProjectNum = a.ProjectNum
You'll need to replace that second instance of qryProjectStatusDPLphase1 with the nested query.

Related

Access DB engine does not recognize field when using Crosstab and subquery joins

I am in MS Access trying to join two queries. The first query is a Crosstab query:
TRANSFORM Sum(Q1.Downtime) AS SumOfDowntime
SELECT Q1.Batch
FROM [QryDowntime] Q1
GROUP BY Q1.Batch
PIVOT Q1.Category;
This runs, no issues. It is summing downtime for OEE for context. Output looks something like:
Batch Availability Performance Quality
1 0 5 2
2 3 1 5
...
I then have a separate query that pulls the date from the previous record:
SELECT B2.Batch,
(SELECT TOP 1 B1.LastPallet
FROM TblBatches AS B1
WHERE B1.ID < B2.ID
ORDER BY B1.ID DESC) AS PrevEnd
FROM TblBatches AS B2;
Again, no issues. This runs and the output looks something like:
Batch PrevEnd
1 8/2/2021
2 8/5/2021
...
I have a summary table and want to join these two.
SELECT B1.Batch,
Q1.Availability,
Q1.Performance,
Q1.Quality,
Q2.PrevEnd
FROM (TblBatches AS B1
LEFT JOIN QryCrosstab AS Q1 ON B1.Batch = Q1.Batch)
LEFT JOIN QryDate AS Q2 ON B1.Batch = Q2.Batch;
I thought this would be the easy part but I get the error "The Microsoft Access database engine does not recognize 'B2.ID' as a valid field name or expression." If I remove either of the joins, the query works fine.
I am aware of this solution but, as the author states, it is not really a solution. I do not want to use more tables if there is another way to fix the error.
I tried this solution but it is not quite the same. I don't really have a subquery I can do beforehand. If I can, I do not know how to do it. There is nothing dynamic. I am not accepting user inputs. These are straightforward queries. I am hoping there is a strange typo or incorrect syntax.
Any ideas would be greatly appreciated!

Query with Totals Query results as criteria returns the expected number of results squared

Background
I am building an Access 2010 database that has a table [ControllerAdjustments] that keeps track of all adjustments made to controllers with an [AdjustmentID] autonumber field, a [ControllerID] field, an [AdjustmentDate] field, [Setpoint] field, and a [Power] field. The [Power] field represents the power level when the adjustment was made. Ultimately I need two queries to return two sets of results, one query should return the current status of all controllers (basically the most recent adjustment made on each controller) and the other should return the most recent adjustment made on each controller where power level is 100%. I plan to use each of these queries to feed a report. Note: field names changed slightly for convenience when typing, full names given in the code blocks...
Method
I focused on the Current Query first, and figured I would just copy it and make necessary changes to create a 100% Query. I started with a totals query on the [ControllerAdjustments] table, that had [ControllerID] as a Group By field and [AdjustmentDate] as a field that returned the Max value. This query returns exactly the number of records I expected, and after reviewing the sample bogus data I put in the table to check it, it seems to return exactly the records I need. I then created a Select Query that returned all the fields I want in my Current Report, namely the [ControllerAdjustments] table and the related records in upstream related tables. I then set the criteria for the [ControllerID] field in my Select Query to equal [Total_CurrentContAdjs]![ControllerID] and the [AdjustmentDate] in the Select Query to [Total_CurrentContAdjs]![MaxOfAdjustmentDate]. Running this query returns exactly what I want. The SQL for this query is below:
SELECT List_Units.UnitID, List_EDTanks.TankNameShort, List_Controllers.ControllerType, ControllerAdjustments.AdjustmentDate, ControllerAdjustments.ControllerSetpoint, ControllerAdjustments.RxPower
FROM Total_ContAdjsCurrent, ((List_Units INNER JOIN List_EDTanks ON List_Units.UnitID = List_EDTanks.UnitID) INNER JOIN List_Controllers ON List_EDTanks.EDTankID = List_Controllers.EDTankID) INNER JOIN ControllerAdjustments ON List_Controllers.ControllerID = ControllerAdjustments.ControllerID
WHERE (((ControllerAdjustments.AdjustmentDate)=[Total_ContAdjsCurrent]![MaxOfAdjustmentDate]) AND ((ControllerAdjustments.ControllerID)=[Total_ContAdjsCurrent]![ControllerID]))
ORDER BY List_Units.Unit, List_EDTanks.TankSortOrder, List_Controllers.ControllerType DESC;
I then copied the Totals query and added a column for Power, selected Where, unchecked show, and put in 100 for criteria. This works as expected. I then copied my select query, and changed the criteria fields to direct to my new 100% Totals query. This is where my problems begin.
Problem
The second 100% Query does not seem to like the criteria, as it initially throws out the familiar parameter window. This is the SQL Statement for the second query, virtually the same except for referring to the 100% Totals query:
SELECT List_Units.UnitID, List_EDTanks.TankNameShort, List_Controllers.ControllerType, ControllerAdjustments.AdjustmentDate, ControllerAdjustments.ControllerSetpoint, ControllerAdjustments.RxPower
FROM Total_ContAdjsCurrent, Total_ContAdjsStdyState, ((List_Units INNER JOIN List_EDTanks ON List_Units.UnitID = List_EDTanks.UnitID) INNER JOIN List_Controllers ON List_EDTanks.EDTankID = List_Controllers.EDTankID) INNER JOIN ControllerAdjustments ON List_Controllers.ControllerID = ControllerAdjustments.ControllerID
WHERE (((ControllerAdjustments.AdjustmentDate)=[Total_ContAdjsStdyState]![MaxOfAdjustmentDate]) AND ((ControllerAdjustments.ControllerID)=[Total_ContAdjsStdyState]![ControllerID]))
ORDER BY List_Units.Unit, List_EDTanks.TankSortOrder, List_Controllers.ControllerType DESC;
Initially, Access did not add my Totals query into the show table box in design view, because its results were not directly used in the Select Query. So, I added the Totals query to the top, and that allowed my query to run without asking for parameters, but now it returns the number of results I was expecting squared. Basically if I am expecting 3 records: 1, 2, and 3, it is giving me: 1, 1, 1, 2, 2, 2, 3, 3, and 3. For the life of me I cannot figure out why it is doing this, especially because the exact same setup for my Current Query returns exactly what is expected... I thought maybe the where clause in my totals query had something to do with it, so I created a Select Query for the [ControllerAdjustments] table that returned all records with 100 for power. I then used this query for my totals query instead of the totals query itself, but this did not do anything different. I am at a loss, and not sure what else I can do to get the results I want. Any suggestions welcome, thank you!
I solved this by simply starting over from scratch and rebuilding my 100% query. Reviewing the SQL statements, they look identical, however for some reason my query now returns the right number of records. I have no idea why this worked, and am still curious what went wrong in the first place if anyone with time available cares to dig into it, but the original problem statement has been corrected--even if I have no idea how I did it haha...

Repeated results from an access query

I am new to Access and acually to db's ,
I'm trying to perform a db for recording the results of a really huge survey. So far everything is ok but now that i am designing the Queries I am getting repeated results and I don't know why.
My SQL Statement is:
SELECT T_VALORACIO.IdValoracio, T_ENQUESTA.Treballador,
T_VALORACIO.IdValPreu
FROM (T_ALSECA INNER JOIN T_VALORACIO ON T_ALSECA.idTipus =
T_VALORACIO.idTipus) INNER JOIN T_ENQUESTA ON T_ALSECA.IdAlseca =
T_ENQUESTA.idAlSeca
WHERE (((T_ENQUESTA.Treballador)=True) AND ((T_VALORACIO.IdValPreu)=4));
I would expect getting the results that fit both cases, but the results that fit just the first case are also shown.
Thanks in advance !
Try using instead:
SELECT DISTINCT
This removes duplicate rows.

Multiple Joins + Lots of Data Optimization

I am working on a massive join at work and have very limited resources in terms of being able to add indexes and such as well as what I can do in the query itself due to the environment (i.e. I can only select data, no variables or table creations allowed). I have read somewhere that a subquery will automatically index the result, is this true? Also for my major join tables (3) each has ~140K rows. I have to join 2 extra tables to ensure filtering is correct. I have the query listed below which I currently have criteria on the JOIN clause. Another question is if I move my criteria to a where clause either in or out of the subquery will it benefit?
SELECT *
FROM (SELECT NULL AS A1,
DFS_ROHEADER.TECHID,
DFS_ROHEADER.RONUMBER,
DFS_ROHEADER.CUSTOMERNUMBER,
DFS_CUSTOMER.BNAME,
DFS_ROHEADER.UNITNUMBER,
DFS_ROHEADER.MILEAGE,
DFS_ROHEADER.OPENEDDATE,
DFS_ROHEADER.CLOSEDDATE,
DFS_ROHEADER.STATUS,
DFS_ROHEADER.PONUMBER,
DFS_TECH.REGION,
DFS_TECH.RSM,
DFS_ROPART.PARTID,
CONVERT(NVARCHAR(max), DFS_RODETAIL.STORY) AS STORY
FROM DFS_ROHEADER
LEFT JOIN DFS_CUSTOMER
ON DFS_ROHEADER.CUSTOMERNUMBER = DFS_CUSTOMER.CUST_NO
LEFT JOIN DFS_TECH
ON DFS_ROHEADER.TECHID = DFS_TECH.TECHID
INNER JOIN DFS_RODETAIL
ON DFS_ROHEADER.RONUMBER = DFS_RODETAIL.RONUMBER
INNER JOIN DFS_ROPART
ON DFS_RODETAIL.RONUMBER = DFS_ROPART.RONUMBER
AND DFS_RODETAIL.LINENUMBER = DFS_ROPART.LINENUMBER
AND DFS_ROHEADER.RONUMBER LIKE '%$FF_RONumber%'
AND DFS_ROHEADER.UNITNUMBER LIKE '%$FF_UnitNumber%'
AND DFS_ROHEADER.PONUMBER LIKE '%$FF_PONumber%'
AND ( DFS_CUSTOMER.BNAME LIKE '%$FF_Customer%'
OR DFS_CUSTOMER.BNAME IS NULL )
AND DFS_ROHEADER.TECHID LIKE '%$FF_TechID%'
AND DFS_ROHEADER.CLOSEDDATE BETWEEN
FF_ClosedBegin AND FF_ClosedEnd
AND ( DFS_TECH.REGION LIKE '%$FilterRegion%'
OR DFS_TECH.REGION IS NULL )
AND ( DFS_TECH.RSM LIKE '%$FF_RSM%'
OR DFS_TECH.RSM IS NULL )
AND DFS_RODETAIL.STORY LIKE '%$FF_Story%'
AND DFS_ROPART.PARTID LIKE '%$FF_PartID%'
WHERE DFS_ROHEADER.DELETED_BY < 0
AND DFS_RODETAIL.DELETED_BY < 0
AND DFS_ROPART.DELETED_BY < 0) T
ORDER BY T.RONUMBER
This query works; however, it can take forever to run, and can timeout. I have other queries that also run in the environment and I will take whatever you can give me in terms of suggestions and apply it to those. I am using SQLServer 2000, Thanks for the help.
EDIT:
Execution Plan:
https://dl.dropboxusercontent.com/u/99733863/ExecutionPlan.sqlplan
UPDATE:
I have come to the conclusion the environment I'm working in is the cause of the problem. My query works as intended and is not slow at all (1 sec. for 18,000 rows). As stated in the comments I have to fill grids with limited flexibility and I believe that these grids fill by first filling a temporary grid with the SQL statement and then copying row by row into the desired grid. There is a good chance that this is the cause of my issues. Thanks for the help.
I have come to the conclusion the environment I'm working in is the cause of the problem. My query works as intended and is not slow at all (1 sec. for 18,000 rows). As stated in the comments I have to fill grids with limited flexibility and I believe that these grids fill by first filling a temporary grid with the SQL statement and then copying row by row into the desired grid. There is a good chance that this is the cause of my issues. Thanks for the help everyone.
My 2 cents here.. In general LIKE is not very well optimized. In your case you also seem to be using LIKE with '%value%'. In that case the query optimizer has to scan the entire index. At a minimum I would see if there is a way to avoid using this.

Oracle SQL - Comparing AVG functions in WHERE

I'm trying to write a few Oracle SQL scripts for an assignment. I've managed to get all of it to work, except for one part. To summarize, I have to display data from 2 tables if the average of 1 column in table A is greater than the average of another column in table B. I realize you cannot include AVG functions in a WHERE clause or HAVING clause since it seems unable to properly access the data (from what I've read). When I exclude this clause, the script executes properly, so I'm confident there are no other errors.
I've tried writing it as follows but the error I get is ORA-00936: missing expression and it is just before the > sign. I thought this may be due to improper bracket placing but none of my attempts resolved this. Here is my attempt:
SELECT l.l_category, SUM(r.r_sold), AVG(l.l_cost)
FROM promos l
INNER JOIN sales r
ON r.promo_id = l.promo_id
GROUP BY l.l_category
HAVING (SELECT AVG(l.l_cost) OVER (PARTITION BY l.l_cost)) >
(SELECT AVG(r.r_sold) OVER (PARTITION BY r.r_sold));
I tried doing this without the OVER (PARTITION BY ...) as well as putting it into a WHERE clause but it didn't resolve the error. I'm pretty sure I need to put it into a SELECT statement somehow but I'm at a loss.
You do not need to use the OVER clause when applying the aggregate functions in the HAVING clause. Just use the aggregate functions on their own.
SELECT l.l_category, SUM(r.r_sold), AVG(l.l_cost)
FROM promos l
INNER JOIN sales r
ON r.promo_id = l.promo_id
GROUP BY l.l_category
HAVING HAVING AVG(l.l_cost) > AVG(r.r_sold)