Select from named query - sql

I have issue with following query in MS Access 2013:
SELECT *
FROM (((
(SELECT Stop.TAGeoID AS TAGeoID,
Trip.TripNo AS TripNo
FROM ((((Trip
INNER JOIN BTStopTimes ON Trip.TripNo = BTStopTimes.TripNumber)
INNER JOIN TripsTxt ON (Trip.TripNo = TripsTxt.trip_id
AND Left(TripsTxt.shape_id, 3) <> 'ELD'))
INNER JOIN PatternDetail ON Trip.PatternID = PatternDetail.PatternID
AND BTStopTimes.Sequence = PatternDetail.StopSortOrder)
INNER JOIN Stop ON Stop.GeoID = PatternDetail.GeoID)) AS t3
LEFT JOIN
(SELECT F10,
F16
FROM PatternStopsRaw
WHERE F16 <> ''
GROUP BY F10,
F16)R ON R.F10 = t3.TAGeoID)
LEFT JOIN Timepoint ON Timepoint.PlaceID = R.F16)
LEFT JOIN
(SELECT *
FROM t3
INNER JOIN TripDetail ON t3.TripNo = TripDetail.TripNo)TripTripDetail ON (Timepoint.TimePointID = TripTripDetail.TimepointID))
It says that there is syntax error
The Microsoft Access database engine cannot find the input table or query t3. Make sure it exists and that its name is spelled correctly
It seems that Access does not allow selecting from the named query in the same query.
Any suggestions?
PS: * are used only for testing purposes, I'll remove them once I have working query.

Yes, it appears that Access does not recognize the [t3] alias at that level. Perhaps you could try creating the query...
SELECT Stop.TAGeoID AS TAGeoID,
Trip.TripNo AS TripNo
FROM ((((Trip
INNER JOIN BTStopTimes ON Trip.TripNo = BTStopTimes.TripNumber)
INNER JOIN TripsTxt ON (Trip.TripNo = TripsTxt.trip_id
AND Left(TripsTxt.shape_id, 3) <> 'ELD'))
INNER JOIN PatternDetail ON Trip.PatternID = PatternDetail.PatternID
AND BTStopTimes.Sequence = PatternDetail.StopSortOrder)
INNER JOIN Stop ON Stop.GeoID = PatternDetail.GeoID)
...as a saved query in Access, name it [t3], and then just reference that in your main query.

Related

Speed up SQL query performance with nested queries

Could anyone help me speed this query up? It currently take 17 minutes to run but does return the correct data and it populates a subform in MS Access. Functions in the rest of the VBA are declared as long to try to speed up more.
Here's the full query:
SELECT lots of things
FROM (((((((((((((((ngstest
INNER JOIN patients
ON ngstest.internalpatientid = patients.internalpatientid)
INNER JOIN referral
ON ngstest.referralid = referral.referralid)
INNER JOIN checker
ON ngstest.bookby = checker.check1id)
INNER JOIN ngspanel
ON ngstest.ngspanelid = ngspanel.ngspanelid)
LEFT JOIN ngspanel AS ngspanel_1
ON ngstest.ngspanelid_b = ngspanel_1.ngspanelid)
INNER JOIN status
ON ngstest.statusid = status.statusid)
INNER JOIN dbo_patient_table
ON patients.patientid = dbo_patient_table.patienttrustid)
LEFT JOIN dna
ON ngstest.dna = dna.dnanumber)
INNER JOIN status AS status_1
ON patients.s_statusoverall = status_1.statusid)
LEFT JOIN gw_gendertable
ON dbo_patient_table.genderid = gw_gendertable.genderid)
LEFT JOIN ngswesbatch
ON ngstest.wesbatch = ngswesbatch.ngswesbatchid)
LEFT JOIN checker AS checker_1
ON ngstest.check1id = checker_1.check1id)
LEFT JOIN checker AS checker_2
ON ngstest.check2id = checker_2.check1id)
LEFT JOIN checker AS checker_3
ON ngstest.check3id = checker_3.check1id)
LEFT JOIN ngspanel AS ngspanel_2
ON ngstest.ngspanelid_c = ngspanel_2.ngspanelid)
LEFT JOIN checker AS checker_4
ON ngstest.check4id = checker_4.check1id
WHERE ((ngstest.referralid IN
(SELECT referralid FROM referral
WHERE grouptypeid = 14)
AND ngstest.ngstestid IN
(SELECT ngstest.ngstestid
FROM ngsanalysis
INNER JOIN ngstest
ON ngsanalysis.ngstestid = ngstest.ngstestid
WHERE ngsanalysis.pedigree = 3302) )
AND status.statusid = 1202218800)
ORDER BY ngstest.priority,
ngstest.daterequested;
The two nested queries are strings from elsewhere in the code so are called in the vba as " & includereferralls & " And " & ParentsStatusesFilter & "
They are:
ParentsStatusesFilter = "NGSTest.NGSTestID in
(SELECT NGSTest.NGSTestID
FROM NGSAnalysis
INNER JOIN NGSTest
ON NGSAnalysis.NGSTestID = NGSTest.NGSTestID
WHERE NGSAnalysis.Pedigree IN (3302,3303,3304)"
And
includereferrals = "NGSTest.ReferralID
(SELECT referralid FROM referral WHERE referral.grouptypeid = 14)"
The query needs to remain readable (and therefore editable) so can't use things like Distinct, Group By or contain any Unions. Have tried Exists instead of In for the nested queries but that stops it from actually filtering the results.
WHERE EXISTS (SELECT NGSTest.NGSTestID
FROM NGSAnalysis
INNER JOIN NGSTest
ON NGSAnalysis.NGSTestID = NGSTest.NGSTestID
WHERE NGSAnalysis.Pedigree IN (3302,3303,3304)
So the exist clause you have there isn't tied to the outer query which would run similar to just added 1 = 1 to the where clause. I took your where clause and converted it. It should look something like this...
WHERE EXISTS (
SELECT referralid
FROM referral
WHERE grouptypeid = 14 AND ngstest.referralid = referral.referralid)
AND EXISTS (
SELECT ngsanalysis.ngstestid
FROM ngsanalysis
WHERE ngsanalysis.pedigree IN (3302,3303,3304) AND ngstest.ngstestid = ngsanalysis.ngstestid
)
AND status.statusid = 1202218800
Adding exists will speed it up a bit, but the the bulk of the slowness is the left joins. Access does not handle the left joins as well as SQL Server does. Change all your joins to inner joins and you will see the query runs very fast. This is obviously not ideal since some relationships are optional. What I have done to get around this is add a default record that replaces a null relationship.
Here is what that looks like for you: In the checker table you could add a record that represents a null value. So put a record into the checker table with check1id of -1 or 0. Then default check1id, check2id, check3id on ngstest to -1 or 0. You will need to do that type of thing for all tables you need to left join on.

Access Query - Group by and Max

I have been working on this for a few hours now and just can not figure it out.
How would I go about sorting this query by enco_id and only having the max of each clpr_id show up. for example:
Here is my MSAccess Sql Code
SELECT dbo_Client.med_rec_no, dbo_Encounter.episode_number, dbo_client_program.enco_id, dbo_client_program.clpr_id, dbo_client_program.prle_id, dbo_PROGRAM_LEVEL.prle_name, dbo_Client.fname, dbo_Client.lname, dbo_DISCHARGE_STATUS.dist_name, DS2.dist_name
FROM (((((dbo_Client INNER JOIN dbo_Encounter ON dbo_Client.client_id = dbo_Encounter.client_id) INNER JOIN dbo_Episode_info ON dbo_Encounter.enco_id = dbo_Episode_info.enco_id) INNER JOIN dbo_DISCHARGE_STATUS ON dbo_Episode_info.dist_id = dbo_DISCHARGE_STATUS.dist_id) INNER JOIN dbo_client_program ON dbo_Encounter.enco_id = dbo_client_program.enco_id) INNER JOIN dbo_DISCHARGE_STATUS AS DS2 ON dbo_client_program.dist_id = DS2.dist_id) INNER JOIN dbo_PROGRAM_LEVEL ON dbo_client_program.prle_id = dbo_PROGRAM_LEVEL.prle_id;
Also here is what my query looks like
EDIT:
This is the code I am trying to use now and it still is not working
SELECT dbo_Client.client_id, dbo_Client.med_rec_no, dbo_Encounter.episode_number, dbo_Encounter.start_date, dbo_Encounter.end_date, dbo_client_program.clpr_id, dbo_client_program.enco_id, dbo_PROGRAM_LEVEL.prle_name, dbo_Client.fname, dbo_Client.lname, dbo_DISCHARGE_STATUS.dist_name, DS2.dist_name
FROM (((((dbo_Client INNER JOIN dbo_Encounter ON dbo_Client.client_id = dbo_Encounter.client_id) INNER JOIN dbo_Episode_info ON dbo_Encounter.enco_id = dbo_Episode_info.enco_id) INNER JOIN dbo_DISCHARGE_STATUS ON dbo_Episode_info.dist_id = dbo_DISCHARGE_STATUS.dist_id) INNER JOIN dbo_client_program ON dbo_Encounter.enco_id = dbo_client_program.enco_id) INNER JOIN dbo_DISCHARGE_STATUS AS DS2 ON dbo_client_program.dist_id = DS2.dist_id) INNER JOIN dbo_PROGRAM_LEVEL ON dbo_client_program.prle_id = dbo_PROGRAM_LEVEL.prle_id
WHERE dbo_client_program.clpr_id IN
(SELECT TOP 1 clpr_id FROM dbo_client_program as New
WHERE New.clpr_id = dbo_client_program.clpr_id
ORDER by dbo_client_program.clpr_id DESC) AND (dbo_DISCHARGE_STATUS.dist_name <> DS2.dist_name) AND dbo_Encounter.start_date > #1/1/2020# AND dbo_Encounter.end_date > #1/1/2020#
ORDER BY dbo_Encounter.episode_number;
As you are still understanding the aggregate queries my suggestion is:
1-Create a query where you group by all fields and max(clpr_id). Save this as "Query1"
2-Create another query based on "Query1" and sort by "enco_id "

syntax error in from clause in access

Below is my query and it says syntax error in from clause whereas it is perfectly working in SQL.After the error 'AS' is highlighted
SELECT
Table1.*,
emp_details_full1.*
FROM Table1
LEFT JOIN
((SELECT
iss_personal_detail.Specialization,
iss_personal_detail.New_rank,
iss_personal_detail.Induction_tr,
iss_personal_detail.Title,
iss_personal_detail.f_name,
iss_personal_detail.m_name,
iss_personal_detail.l_name,
iss_personal_detail.Father_Hus_Name,
iss_personal_detail.Category,
iss_personal_detail.Community,
iss_personal_detail.SEX,
iss_personal_detail.source_recruit,
iss_personal_detail.Pay_Parity,
iss_personal_detail.[Date_Pay_Parity],
iss_personal_detail.UPSC_Rank,
iss_personal_detail.dob,
iss_personal_detail.doj_govt,
iss_personal_detail.DOA_ISS,
iss_personal_detail.Batch,
iss_personal_detail.Year_of_Exam,
iss_personal_detail.Native_Distt,
iss_personal_detail.Native_State,
iss_personal_detail.[Highest Qualification],
iss_personal_detail.Languages_Known,
iss_personal_detail.Mother_Toung,
iss_personal_detail.Marital_Status,
iss_personal_detail.E_mail_ID,
iss_personal_detail.retire_reason,
iss_personal_detail.title_m,
Present_Posting.*,
ISS_MINISTRY_CODE_LIST.*,
ISS_DEPARTMENT_CODE_LIST.*,
ISS_CITY_CODE_LIST.*,
Desig_Code.*,
Grade_Code.Grade_code
FROM ISS_CITY_CODE_LIST
INNER JOIN( Grade_Code
INNER JOIN (Desig_Code
INNER JOIN (((iss_personal_detail
INNER JOIN Present_Posting
ON iss_personal_detail.OID = Present_Posting.OID)
INNER JOIN ISS_MINISTRY_CODE_LIST
ON Present_Posting.ministry = ISS_MINISTRY_CODE_LIST.MINISTRY_CODE)
INNER JOIN ISS_DEPARTMENT_CODE_LIST
ON Present_Posting.department = ISS_DEPARTMENT_CODE_LIST.DEPARTMENT_CODE)
ON Desig_Code.Code = Present_Posting.designation)
ON Grade_Code.Grade_code = Present_Posting.Grade)
ON ISS_CITY_CODE_LIST.city_code=Present_Posting.office_city
)) AS emp_details_full1 ON
(emp_details_full1.DEPARTMENT_CODE=Table1.department) AND
(emp_details_full1.MINISTRY_CODE=Table1.ministry) AND
(emp_details_full1.city_code=Table1.city) AND
(emp_details_full1.Grade_Code=Table1.grade)
WHERE Table1.grade='02';
The first thing I would do is take the inner select and create a view from it.
This will provide a simple, easy to read, easy to debug sql code.
CREATE VIEW emp_details_full1
AS
SELECT iss_personal_detail.Specialization, iss_personal_detail.New_rank,
iss_personal_detail.Induction_tr, iss_personal_detail.Title,
iss_personal_detail.f_name, iss_personal_detail.m_name,
iss_personal_detail.l_name, iss_personal_detail.Father_Hus_Name,
iss_personal_detail.Category, iss_personal_detail.Community,
iss_personal_detail.SEX, iss_personal_detail.source_recruit,
iss_personal_detail.Pay_Parity, iss_personal_detail.[Date_Pay_ Parity],
iss_personal_detail.UPSC_Rank, iss_personal_detail.dob,
iss_personal_detail.doj_govt, iss_personal_detail.DOA_ISS,
iss_personal_detail.Batch, iss_personal_detail.Year_of_Exam,
iss_personal_detail.Native_Distt, iss_personal_detail.Native_State,
iss_personal_detail.[Highest Qualification],
iss_personal_detail.Languages_Known,
iss_personal_detail.Mother_Toung, iss_personal_detail.Marital_Status,
iss_personal_detail.E_mail_ID, iss_personal_detail.retire_reason,
iss_personal_detail.title_m, Present_Posting., ISS_MINISTRY_CODE_LIST.,
ISS_DEPARTMENT_CODE_LIST., ISS_CITY_CODE_LIST., Desig_Code.*,
Grade_Code.Grade_code
FROM ISS_CITY_CODE_LIST INNER JOIN( Grade_Code INNER JOIN (Desig_Code INNER JOIN
(((iss_personal_detail INNER JOIN Present_Posting ON iss_personal_detail.OID =
Present_Posting.OID) INNER JOIN ISS_MINISTRY_CODE_LIST
ON Present_Posting.ministry = ISS_MINISTRY_CODE_LIST.MINISTRY_CODE)
INNER JOIN ISS_DEPARTMENT_CODE_LIST ON
Present_Posting.department = ISS_DEPARTMENT_CODE_LIST.DEPARTMENT_CODE) ON
Desig_Code.Code = Present_Posting.designation) ON Grade_Code.Grade_code =
Present_Posting.Grade)
ON ISS_CITY_CODE_LIST.city_code=Present_Posting.office_city
Then the rest of the sql would look like this:
SELECT Table1.,emp_details_full1.
FROM Table1 LEFT JOIN emp_details_full1
ON (emp_details_full1.DEPARTMENT_CODE=Table1.department) AND
(emp_details_full1.MINISTRY_CODE=Table1.ministry) AND
(emp_details_full1.city_code=Table1.city) AND
(emp_details_full1.Grade_Code=Table1.grade) WHERE Table1.grade='02';
Now, if you look closely, you can see that there is a closing bracket missing between the end of the ON clause and the start of the WHERE clause.
So to fix that:
SELECT Table1.,emp_details_full1.
FROM Table1 LEFT JOIN emp_details_full1
ON (emp_details_full1.DEPARTMENT_CODE=Table1.department) AND
(emp_details_full1.MINISTRY_CODE=Table1.ministry) AND
(emp_details_full1.city_code=Table1.city) AND
(emp_details_full1.Grade_Code=Table1.grade)) WHERE Table1.grade='02';
Isn't that much easier to work with?

Using left join and inner join in the same query

Below is my query using a left join that works as expected. What I want to do is add another table filter this query ever further but having trouble doing so. I will call this new table table_3 and want to add where table_3.rwykey = runways_updatable.rwykey. Any help would be very much appreciated.
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
'*************EDIT To CLARIFY *****************
Here is the other statement that inner join i would like to use and I would like to combine these 2 statements.
SELECT *
FROM RUNWAYS_UPDATABLE A, RUNWAYS_TABLE B
WHERE A.RWYKEY = B.RWYKEY
'***What I have so far as advice taken below, but getting syntax error
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*, AIRPORT_RUNWAYS_SELECTED.*
FROM RUNWAYS_UPDATABLE
INNER JOIN AIRPORT_RUNWAYS_SELECTED
ON RUNWAYS_UPDATABLE.RWYKEY = AIRPORT_RUNWAYS_SELECTED.RWYKEY
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
NOTE: If i comment out the inner join and leave the left join or vice versa, it works but when I have both of joins in the query, thats when im getting the syntax error.
I always come across this question when searching for how to make LEFT JOIN depend on a further INNER JOIN. Here is an example for what I am searching when I am searching for "using LEFT JOIN and INNER JOIN in the same query":
SELECT *
FROM foo f1
LEFT JOIN (bar b1
INNER JOIN baz b2 ON b2.id = b1.baz_id
) ON
b1.id = f1.bar_id
In this example, b1 will only be included if b2 is also found.
Remember that filtering a right-side table in left join should be done in join itself.
select *
from table1
left join table2
on table1.FK_table2 = table2.id
and table2.class = 'HIGH'
I finally figured it out. Thanks for all your help!!!
SELECT * FROM
(AIRPORT_RUNWAYS_SELECTED
INNER JOIN RUNWAYS_UPDATABLE
ON AIRPORT_RUNWAYS_SELECTED.RWYKEY = RUNWAYS_UPDATABLE.RWYKEY)
LEFT JOIN TURN_UPDATABLE ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
Add your INNER_JOIN before your LEFT JOIN:
SELECT *
FROM runways_updatable ru
INNER JOIN table_3 t3 ON ru.rwykey = t3.rwykey
LEFT JOIN turn_updatable tu
ON ru.rwykey = tu.rwykey
AND (tu.airline_code IS NULL OR tu.airline_code = '' OR tu.airline_code = '')
WHERE ru.icao = 'ICAO'
AND (ru.tora > 4000 OR ru.lda > 0)
If you LEFT JOIN before your INNER JOIN, then you will not get results from table_3 if there is no matching row in turn_updatable. It's possible this is what you want, but since your join condition for table_3 only references runways_updatable, I would assume that you want a result from table_3, even if there isn't a matching row in turn_updatable.
EDIT:
As #NikolaMarkovinović pointed out, you should filter your LEFT JOIN in the join condition itself, as you see above. Otherwise, you will not get results from the left-side table (runways_updatable) if that condition isn't met in the right-side table (turn_updatable).
EDIT 2: OP mentioned this is actually Access, and not MySQL
In Access, perhaps it's a difference in the table aliases. Try this instead:
SELECT [ru].*, [tu].*, [ars].*
FROM [runways_updatable] AS [ru]
INNER JOIN [airport_runways_selected] AS [ars] ON [ru].rwykey = [ars].rwykey
LEFT JOIN [turn_updatable] AS [tu]
ON [ru].rwykey = [tu].rwykey
AND ([tu].airline_code IS NULL OR [tu].airline_code = '' OR [tu].airline_code = '')
WHERE [ru].icao = 'ICAO'
AND ([ru].tora > 4000 OR [ru].lda > 0)
If it is just an inner join that you want to add, then do this. You can add as many joins as you want in the same query. Please update your answer if this is not what you want, though
SELECT *
FROM RUNWAYS_UPDATABLE
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
INNER JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
I am not really sure what you want. But maybe something like this:
SELECT RUNWAYS_UPDATABLE.*, TURN_UPDATABLE.*
FROM RUNWAYS_UPDATABLE
JOIN table_3
ON table_3.rwykey = runways_updatable.rwykey
LEFT JOIN TURN_UPDATABLE
ON RUNWAYS_UPDATABLE.RWYKEY = TURN_UPDATABLE.RWYKEY
WHERE RUNWAYS_UPDATABLE.ICAO = 'ICAO'
AND (RUNWAYS_UPDATABLE.TORA > 4000 OR LDA > 0)
AND (TURN_UPDATABLE.AIRLINE_CODE IS NULL OR TURN_UPDATABLE.AIRLINE_CODE = ''
OR TURN_UPDATABLE.AIRLINE_CODE = '')
For Postgres, query planner does not guarantee order of execution of join. To Guarantee one can use #Gajus solution but the problem arises if there are Where condition for inner join table's column(s). Either one would to require to carefully add the where clauses in the respective Join condition or otherwise it is better to use subquery the inner join part, and left join the output.

SQL Server update with joins

I am trying to update a date in a table, based off of a MAX(date) in another table. To get the correct data to link up, I have to do 2 inner joins and 2 left outer joins.
I can select the correct data, it returns a Guid (PersonId) and the Date.
I have to use this information to update my original table. I am having trouble getting this to work, I still getting syntax errors.
update tblqualityassignments as assign
inner join tblrequirementteams as team on assign.guidmemberid = team.guidmemberid
set assign.dtmQAPCLed = dtmTaken
from
(
select reg.guidpersonid, max(certs.dtmTaken) as dtmTaken from tblqualityassignments as assign
inner join tblrequirementteams as team on assign.guidmemberid = team.guidmemberid
inner join tblregisteredusercerts as reg on team.guidpersonid = reg.guidpersonid
left outer join tblcerttaken as certs on certs.guidcertid = reg.guidcertid
left outer join tblCodesCertType as types on types.intcerttypeid = certs.intcerttypeid
where types.intcerttypeid = 1
and assign.guidmemberid = team.guidmemberid
group by reg.guidpersonid as data
)
where data.guidpersonid = team.guidpersonid
Assuming you are using SQL Server for this, then this should work:
UPDATE A
SET A.dtmQAPCLed = dtmTaken
FROM tblqualityassignments AS A
INNER JOIN tblrequirementteams as T
ON A.guidmemberid = T.guidmemberid
INNER JOIN (select reg.guidpersonid, max(certs.dtmTaken) as dtmTaken
from tblqualityassignments as assign
inner join tblrequirementteams as team
on assign.guidmemberid = team.guidmemberid
inner join tblregisteredusercerts as reg
on team.guidpersonid = reg.guidpersonid
left outer join tblcerttaken as certs
on certs.guidcertid = reg.guidcertid
left outer join tblCodesCertType as [types]
on [types].intcerttypeid = certs.intcerttypeid
where [types].intcerttypeid = 1
and assign.guidmemberid = team.guidmemberid
group by reg.guidpersonid) data
ON T.guidpersonid = data.guidpersonid