MS Access SQL sub Query using outer query result - sql

I'm attempting to run a sub query based on the result of an outer query. The issue that I am having is that instead of using the outer query, I get a prompt for a value from the subquery.
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities
The goal is that the sub query should use the value from Facilities.AppCo1 to match with the value in YeildDB.FIPS and then return the corresponding value in YeildDB.CornYeild.
Currently I get a prompt asking for the YeildDB.FIPS value instead of the sub query using the outer query value.

Your code should work. But you can also express this using a LEFT JOIN:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
YeildDB.CornYield
FROM Facilities LEFT JOIN
YeildDB
ON Facilties.AppCo1 = YeildDB.FIPS;
I noticed that you misspelled Facilities -- and that is probably why your version doesn't work. This is one reason to use table aliases:
SELECT f.CustomerName, f.FacilityName,
f.AnnualPlan, f.AppCo1,
y.CornYield
FROM Facilities as f LEFT JOIN
YeildDB as y
ON f.AppCo1 = y.FIPS;

Your sub query may be returning multiple values, hence the prompt asking you to specify which one you want. You can fix this (or at least hide this issue) by specifying top 1:
SELECT Facilities.CustomerName, Facilities.FacilityName,
Facilities.AnnualPlan, Facilities.AppCo1,
(SELECT TOP 1 YeildDB.CornYield
FROM YeildDB
WHERE Facilites.AppCo1 = YeildDB.FIPS) AS Expr1
FROM Facilities

Related

Error in using subquery in access join query

I need to use the result of a query as a lookup field for another query. What I tried was using a sub query aliased as something, but finally I got some error saying "enter parameter value" for variz.variz and Y.varizname.
I've searched in forums, but I can't find any similar problem.
SELECT sahmeharkas.attrib,
[sahmeharkas]![expenseper] AS Expense,
variz.variz
FROM sahmeharkas
LEFT JOIN
(SELECT variz.varizname FROM variz GROUP BY variz.varizname) as Y
ON sahmeharkas.attrib = Y.variz.varizname
The table variz does not exist outside of the subquery; you should instead use the subquery alias as the table qualifier, e.g.:
select s.attrib, s.expenseper as expense, y.variz
from
sahmeharkas s left join
(select v.variz, v.varizname from variz v group by v.variz, v.varizname) y on
s.attrib = y.varizname

Microsoft Access 2016: Conditional Inner Join Multiple Cases

I hope what I'm asking for makes sense. I would like to have a query that chooses a specific type of Inner Join based on a user input.
This is what I have.
Queries:
qryFiltered (Main Query)
qryLand (sub)
qrySea (sub)
qryAllOrder (sub)
Tables:
tblLowPriority
Forms:
EnterWork (which has a option group called ogLandSea)
In my main query "qryFiltered", I have the following SQL code:
SELECT qryAllOrder.*
FROM
SWITCH
(Forms!EnterWork!ogLandSea = 1, (qryAllOrder LEFT JOIN tblLowPriority ON qryAllOrder.[WORK_ORDER_NBR] = tblLowPriority.[WO]) INNER JOIN qrySea ON qryAllOrder.WORK_ORDER_NBR = qrySea.WORK_ORDER_NBR,
Forms!EnterWork!ogLandSea = 2, (qryAllOrder LEFT JOIN tblLowPriority ON qryAllOrder.[WORK_ORDER_NBR] = tblLowPriority.[WO]) INNER JOIN qryLand ON qryAllOrder.WORK_ORDER_NBR = qryLand.WORK_ORDER_NBR)
WHERE tblLowPriority.WO Is Null
Basically, what I'm looking for is to choose the join based on what the user selects on the form. The inner join would choose either qrySea or qryLand based on this input. The error I'm getting is: "Syntax error in FROM clause."
What am I doing wrong here? It's the Switch function that's not working. I tried the two Land and Sea options separately without the Switch function and it works. I just can't seem to figure out a way to have the Inner Join change based on user input.
Appreciate all your responses!
I was able to get this to work by doing a Left Join from the main query to the two subqueries. And then I put a Switch criteria in the WHERE Clause:
WHERE (Switch([Forms]![EnterWork]![ogLandSea]=1,[qrySea]![WORK_ORDER_NBR] Is Not Null Or [qrySea]![WORK_ORDER_NBR] Is Null Or [qryLand]![WORK_ORDER_NBR] Is Not Null,[Forms]![EnterWork]![ogLandSea]=2,[qrySea]![WORK_ORDER_NBR] Is Not Null,[Forms]![EnterWork]![ogLandSea]=3,[qryLand]![WORK_ORDER_NBR] Is Not Null,[Forms]![EnterWork]![ogFN]=4,[qrySea]![WORK_ORDER_NBR] Is Null And [qryLand]![WORK_ORDER_NBR] Is Null))<>False)
Basically, this is what it does:
Option 1: Display all records from the Main Query
Option 2: Display only records that are in qrySea
Option 3: Display only records that are in qryLand
Option 4: Display only records that are NOT in qrySea nor qryLand

Two almost identical queries returning different results

I am getting different results for the following two queries and I have no idea why. The only difference is one has an IN and one has an equals.
Before I go into the queries you should know that I found a better way to do it by moving the subquery into a common table expression, but this is still driving me crazy! I really want to know what caused the issue in the first place, I am asking out of curiosity
Here's the first query:
use [DB.90_39733]
Select distinct x.uniqproducer, cn.Firstname,cn.lastname,e.code,
ecn.FirstName, ecn.LastName, ecn.entid, x.uniqline
from product x
join employ e on e.EmpID=x.uniqproducer
join contactname cn on cn.uniqentity=e.uniqentity
join [ETL_GAWR92]..idlookupentity ide on ide.enttype='EM'
and ide.UniqEntity=e.UniqEntity
left join [ETL_GAWR92]..EntConName ecn on ecn.entid=ide.empid
and ecn.opt='Y'
Where x.UniqProducer =(SELECT TOP 1 idl.UniqEntity
FROM [ETL_GAWR92]..IDLookupEntity idl
LEFT JOIN [ETL_GAWR92]..Employ e2 ON e2.ProdID = ''
WHERE idl.empID = e2.EmpID AND
idl.EntType = 'EM')
And the second one:
use [DB.90_39733]
Select distinct x.uniqproducer, cn.Firstname,cn.lastname,e.code,
ecn.FirstName, ecn.LastName, ecn.entid, x.uniqline
from product x
join employ e on e.EmpID=x.uniqproducer
join contactname cn on cn.uniqentity=e.uniqentity
join [ETL_GAWR92]..idlookupentity ide on ide.enttype='EM'
and ide.UniqEntity=e.UniqEntity
left join [ETL_GAWR92]..EntConName ecn on ecn.entid=ide.empid
and ecn.opt='Y'
Where x.UniqProducer IN (SELECT TOP 1 idl.UniqEntity
FROM [ETL_GAWR92]..IDLookupEntity idl
LEFT JOIN [ETL_GAWR92]..Employ e2 ON e2.ProdID = ''
WHERE idl.empID = e2.EmpID AND
idl.EntType = 'EM')
The first query returns 0 rows while the second query returns 2 rows.The only difference is x.UniqProducer = versus x.UniqProducer IN for the last where clause.
Thanks for your time
SELECT TOP 1 doesn't guarantee that the same record will be returned each time.
Add an ORDER BY to your select to make sure the same record is returned.
(SELECT TOP 1 idl.UniqEntity
FROM [ETL_GAWR92]..IDLookupEntity idl
LEFT JOIN [ETL_GAWR92]..Employ e2 ON e2.ProdID = ''
WHERE idl.empID = e2.EmpID AND
idl.EntType = 'EM' ORDER BY idl.UniqEntity)
I would guess (with strong emphasis on the word “guess”) that the reason is based on how equals and in are processed by the query engine. For equals, SQL knows it needs to do a comparison with a specific value, where for in, SQL knows it needs to build a subset, and find if the "outer" value is in that "inner" subset. Yes, the end results should be the same as there’s only 1 row returned by the subquery, but as #RickS pointed out, without any ordering there’s no guarantee of which value ends up “on top” – and the (sub)query plan used to build the in - driven subquery might differ from that used by the equals pull.
A follow-up question: which is the correct dataset? When you analyze the actual data, should you have gotten zero, two, or a different number of rows?

MS Access SQL Update with Minimum

This SQL is beyond my expertise. I think it should be fairly easy for someone with experience. Here is what I have so far..
SQL is as follows:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)));
I want to add one last condition to this being that I only want the minimum of [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] to update the table. I've tried the obvious of wrapping the field in Min, and also tried creating a separate aggregate select statement first (to get the min value with other criteria) that I then tried to create the update query from in new query but no luck.
I believe this is valid Access/Jet SQL. The idea here is to use a subquery to look up the earliest date among all the rows in your subset. I'm not sure if ms_itn was the right column to correlate on but hopefully you get the idea:
UPDATE (Tbl_Stg_Project_Schedule_Dates
INNER JOIN Tbl_Child_ITN ON Tbl_Stg_Project_Schedule_Dates.ms_itn = Tbl_Child_ITN.ITN)
INNER JOIN Tbl_Schedule ON Tbl_Child_ITN.Id = Tbl_Schedule.ID
SET Tbl_Schedule.a_construction_start = [Tbl_Stg_Project_Schedule_Dates].[ms_start_date]
WHERE (((Tbl_Stg_Project_Schedule_Dates.ms_tempt_id) In (16,17,18,19,20,21,22,23)))
and [Tbl_Stg_Project_Schedule_Dates].[ms_start_date] = (
select min(sd.[ms_start_date])
from [Tbl_Stg_Project_Schedule_Dates] as sd
where sd.ms_itn = [Tbl_Stg_Project_Schedule_Dates].ms_itn
)

Whats wrong with this nested query?

I am trying to write a query to return the id of the latest version of a market index stored in a database.
SELECT miv.market_index_id market_index_id from ref_market_index_version miv
INNER JOIN ref_market_index mi ON miv.market_index_id = mi.id
WHERE mi.short_name='dow30'
AND miv.version_num = (SELECT MAX(m1.version_num) FROM ref_market_index_version m1 INNER JOIN ref_market_index m2 ON m1.market_index_id = m2.id )
The above SQL statement can be (roughly) translated into the form:
SELECT some columns FROM SOME CRITERIA MATCHED TABLES
WHERE mi.short_name='some name'
AND miv.version_num = SOME NUMBER
What I don't understand is that when I supply an actual number (instead of a sub query), the SQL statement works - also, when I test the SUB query used to determine the latest version number, that also works - however, when I attempt to use the result returned by sub query in the outer (parent?) query, it returns 0 rows - what am I doing wrong here?
Incidentally, I also tried an IN CLAUSE instead of the strict equality match i.e.
... AND miv.version_num IN (SUB QUERY)
That also resulted in 0 rows, although as before, when running the parent query with a hard coded version number, I get 1 row returned (as expected).
BTW I am using postgeresql, but I prefer the solution to be db agnostic.
The problem is probably that the max(version_num) doesn't exist for 'dow30'.
Try the following correlated subquery:
SELECT miv.market_index_id market_index_id
from ref_market_index_version miv INNER JOIN
ref_market_index mi
ON miv.market_index_id = mi.id
WHERE mi.short_name='dow30' AND
miv.version_num = (SELECT MAX(m1.version_num)
FROM ref_market_index_version m1 INNER JOIN
ref_market_index m2
ON m1.market_index_id = m2.id
where m1.short_name = 'dow30'
)
I added the where clause in the subquery.