IF/ELSE LEFT JOIN - mysql

I need to do a LEFT JOIN with IF/ELSE, this is my query:
IF (M.idArtVar=null,
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo),
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo AND
G.idArtVar = M.idArtVar)
)
But it doesn't work.
I also tried like this:
LEFT JOIN ArtMaga AM
ON IF(M.idArtVar IS NULL,
(AM.idMagazzino = TM.idMagazzino AND AM.idArticolo = A.idArticoli),
(AM.idMagazzino = TM.idMagazzino AND AM.idArtVar = M.idArtVar))
But this query is too slow.
How can I do?
Thanks.
EDIT: This is full query:
SELECT F.Codice AS "CodiceFornitore", F.RagioneSociale AS "RagioneSocialeFornitore", A.ArticoloFornitore, C.Descrizione AS CatDes, S.Descrizione AS Settore, U.Sigla AS Um, U2.Sigla AS Um2, A.Moltiplicatore AS Molt, A.Collo, TM.
dMagazzino, M.idArtVar, AM.Esistenza, AM.Disponibilita, AM.QtaImpegnata, AM.QtaOrdinata, TM.TipoSoggetto, TM.idSoggetto, ST.DataMovimento, MC.Codice, ST.Quantita, ST.Prezzo, ST.Sconti, M.idMagaRigMov
FROM MagaRigMov M
LEFT JOIN Articoli A ON A.idArticoli = M.idArticolo
LEFT JOIN UnMisura U ON U.idUnMisura = A.idUnMisura1
LEFT JOIN UnMisura U2 ON U2.idUnMisura = A.idUnMisura2
LEFT JOIN Iva I ON I.idIva = A.idIva
LEFT JOIN Settori S ON S.idSettori = A.idSettore
LEFT JOIN Fornitori F ON F.idFornitori = A.idFornitore
LEFT JOIN ArtCategorie C ON C.idArtCategorie = A.idArtCategoria
LEFT JOIN MagaTesMov TM ON TM.idMagaTesMov = M.idMagaTesMov
LEFT JOIN STORICO ST ON (ST.idSoggetto = TM.idSoggetto AND ST.TipoSoggetto = TM.TipoSoggetto AND ST.idArticolo = M.idArticolo)
LEFT JOIN MagaCausali MC ON MC.idMagaCausali = ST.idMagaCausale
LEFT JOIN ArtMaga AM ON IF(M.idArtVar IS NULL,(AM.idMagazzino = TM.idMagazzino AND AM.idArticolo = A.idArticoli),
(AM.idMagazzino = TM.idMagazzino AND AM.idArtVar = M.idArtVar))
This query is too slow.. but works..

You can't use an IF to make a conditional join. Because IF is not part of the SELECT syntax and even if it was (like CASE expressions) it wouldn't be allowed to be used like this. You can move the logic to the ON statement though:
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo)
AND M.idArtVar IS NULL
OR (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo AND
G.idArtVar = M.idArtVar)
AND M.idArtVar IS NOT NULL
which can be simplified to:
LEFT JOIN ArtMaga G
ON (G.idMagazzino = V.idMagazzino AND G.idArticolo = M.idArticolo)
AND (M.idArtVar IS NULL OR G.idArtVar = M.idArtVar)
Also notice that you can't use equality to check if an expression is null.
M.idArtVar = null will never be true because NULL can never be equal to anything (not even to NULL). The way to check if an expression is null is with IS NULL.
Your second query, that words, is using the IF() function of MySQL and seems to be correct (although I see a difference in the code with the first query, the G.idArticolo = M.idArticolo condition has been removed from one part.)
Why a query is slow depends on many factors and using functions on the join conditions can be one of the many. Try the change I suggest above. If it still slow, you'll have to examine the execution plan and the available indexes on the tables.

Just put the condition in the on clause. If is not part of a SQL statement.
SELECT F.Codice AS "CodiceFornitore", F.RagioneSociale AS "RagioneSocialeFornitore",
A.ArticoloFornitore, C.Descrizione AS CatDes, S.Descrizione AS Settore, U.Sigla AS Um, U2.Sigla AS Um2, A.Moltiplicatore AS Molt, A.Collo, TM.
dMagazzino, M.idArtVar, AM.Esistenza, AM.Disponibilita, AM.QtaImpegnata, AM.QtaOrdinata, TM.TipoSoggetto, TM.idSoggetto, ST.DataMovimento, MC.Codice, ST.Quantita, ST.Prezzo, ST.Sconti, M.idMagaRigMov
FROM MagaRigMov M
LEFT JOIN Articoli A ON A.idArticoli = M.idArticolo
LEFT JOIN UnMisura U ON U.idUnMisura = A.idUnMisura1
LEFT JOIN UnMisura U2 ON U2.idUnMisura = A.idUnMisura2
LEFT JOIN Iva I ON I.idIva = A.idIva
LEFT JOIN Settori S ON S.idSettori = A.idSettore
LEFT JOIN Fornitori F ON F.idFornitori = A.idFornitore
LEFT JOIN ArtCategorie C ON C.idArtCategorie = A.idArtCategoria
LEFT JOIN MagaTesMov TM ON TM.idMagaTesMov = M.idMagaTesMov
LEFT JOIN STORICO ST ON (ST.idSoggetto = TM.idSoggetto AND ST.TipoSoggetto = TM.TipoSoggetto AND ST.idArticolo = M.idArticolo)
LEFT JOIN MagaCausali MC ON MC.idMagaCausali = ST.idMagaCausale
LEFT JOIN ArtMaga AM ON (AM.idMagazzino = TM.idMagazzino AND (m.idartVar is NULL and AM.idArtVar = M.idArtVar or AM.idArticolo = A.idArticoli))

Related

error 1054 unknown column in 'on clause' - inner join as view

Sorry, I'm a newbee here and can't get everyhing right at one time in beautiful code lists. I'm in a prephase to (let) launch my database on a website, but before I do I need to create a (total) view with inner join. And i get a message of the infamous 1054 unknown column in 'on clause'. Here is the actual MySQL script. Can someone help me succeeding the script as a view ? Around this code in the script it stucks (between the stars in the FROM SYNTAX): INNER JOIN zorgaanbieder AS zorgaanbieder_1 ON (zorgverlener.Zorgaanbieder_ID = zorgaanbieder_1.Zorgaanbieder_ID). Please see code below
CREATE VIEW `fetch_data` AS
SELECT
zorgactiviteiten.ZA_code,
zorgactiviteiten.ZA_naam,
zorgactiviteiten.ZA_omschr_consument,
zorgprofielklasse.ZPK_oms,
behandelingen.Behandeling_criteria,
aanspraak.Aanspraak_omschr,
aanspraak.Aanspraak_machtiging,
cluster.Cluster_naam,
diagnosen.Diagnose_code,
diagnosen.Diagnose_naam,
diagnosen.Diagnose_groep,
diagnosen.Diagnose_hoofdstuk,
specialisme.Specialisme_naam,
zorgproducten.ZP_code,
zorgproducten.ZP_naam,
zorgproducten.ZP_omschr_consument,
zorgproductgroepen.ZPG_naam,
declaratie.Declaratie_code,
declaratie.Declaratie_zorg,
contractueel.Contractueel_uitleg,
contract.Contract_zorg,
contract.Contract_verzekerd,
contract.Contract_uitsluiting,
zorgverzekeraar.Zorgverzekeraar_verzekeraar,
zorgverzekeraar.Zorgverzekering_verzekering,
zorgverzekeraar.Zorgverzekering_soort,
zorgverzekeraar.Zorgverzekering_zorgkeuze,
concern.Concern_inkoop,
concern.Concern_label,
zorgverlener.Zorgverlener_plaats,
zorgverlener.Zorgverlener_regio,
zorgverlener.Zorgverlener_soort,
zorgaanbieder.Zorgaanbieder_informatie,
zorgaanbieder.Zorgaanbieder_website,
zorgaanbieder.Zorgaanbieder_reviews,
zorgaanbieder.Zorgaanbieder_rapport,
zorgaanbieder.Zorgaanbieder_oordeel,
zorgaanbieder.Zorgaanbieder_prijslijst,
prijslijst.Prijslijst_tarief,
prijslijst.Prijslijst_actie,
prijslijst.Prijslijst_soort,
prijslijst.Prijslijst_jaar
FROM
concern_zorgaanbieder_prijslijst
INNER JOIN
prijslijst ON (concern_zorgaanbieder_prijslijst.Prijslijst_ID = prijslijst.Prijslijst_ID)
INNER JOIN
concern ON (concern_zorgaanbieder_prijslijst.Concern_ID = concern.Concern_ID)
INNER JOIN
zorgaanbieder ON (concern_zorgaanbieder_prijslijst.Zorgaanbieder_ID = zorgaanbieder.Zorgaanbieder_ID)
INNER JOIN
zorgaanbieder AS zorgaanbieder_1 ON (zorgverlener.Zorgaanbieder_ID = zorgaanbieder_1.Zorgaanbieder_ID)
INNER JOIN
zorgverlener ON (contract.Zorgverlener_koppel = zorgverlener.Zorgverlener_ID)
INNER JOIN
concern AS concern_1 ON (zorgverzekeraar.Concern_ID = concern_1.Concern_ID)
INNER JOIN
zorgverzekeraar ON (contract.Zorgverzekeraar_koppel = zorgverzekeraar.Zorgverzekeraar_ID)
INNER JOIN
contract ON (contractueel_contract.Contract_ID = contract.Contract_ID)
INNER JOIN
contractueel_contract ON (contractueel.Contractueel_ID = contractueel_contract.Contract_ID)
INNER JOIN
contractueel ON (contractueel_decaratie.Contractueel_ID = contractueel.Contractueel_ID)
INNER JOIN
contractueel_decaratie ON (declaratie.Declaratie_code = contractueel_decaratie.Declaratie_code)
INNER JOIN
declaratie ON (zorgproducten_declaratie.Declaratie_code = declaratie.Declaratie_code)
INNER JOIN
zorgproducten_declaratie ON (zorgproducten.ZP_code = zorgproducten_declaratie.ZP_code)
INNER JOIN
zorgproductgroepen ON (zorgproducten.ZPG_code = zorgproductgroepen.ZPG_code)
INNER JOIN
zorgproducten ON (dbc.ZP_code = zorgproducten.ZP_code)
INNER JOIN
specialisme ON (diagnosen.Specialisme_code = specialisme.Specialisme_code)
INNER JOIN
diagnosen ON (diagnosebereik.Diagnose_ID = diagnosen.Diagnose_ID)
INNER JOIN
diagnosebereik ON (dbc_diagnosebereik.Diagnosebereik_naam = diagnosebereik.Diagnosebereik_naam)
INNER JOIN
dbc_diagnosebereik ON (diagnosebereik.Diagnosebereik_naam = dbc_diagnosebereik.Diagnosebereik_naam)
INNER JOIN
dbc ON (dbc_diagnosebereik.DBC_koppel = dbc.DBC_koppel)
INNER JOIN
behandelingen ON (dbc.DBC_koppel = behandelingen.DBC_koppel)
INNER JOIN
cluster ON (behandelingen.Cluster_ID = cluster.Cluster_ID)
INNER JOIN
aanspraak ON (behandelingen.Aanspraak_code = aanspraak.Aanspraak_code)
INNER JOIN
zorgactiviteit_behandelingen ON (behandelingen.Behandeling_naam = zorgactiviteit_behandelingen.Behandeling_naam)
INNER JOIN
zorgactiviteiten ON (zorgactiviteit_behandelingen.ZA_code = zorgactiviteiten.ZA_code)
INNER JOIN
zorgprofielklasse ON (zorgactiviteiten.ZPK_code = zorgprofielklasse.ZPK_code)
Debugging advice: Start small, test, then by grow by small increments and re-test.
I believe you problem is INCORRECT SEQUENCE of joins, NOT incorrect column references. e.g.
## this will fail
select a.* from a
join c on b.id = c.id ## c attempts to join to b = incorrect sequence of joins
join b on a.id = b.id
Below, table zorgverlener attempts to join to contract but it has not yet been joined.
SELECT
czp.*
FROM concern_zorgaanbieder_prijslijst as czp
...
INNER JOIN zorgverlener ON (contract.Zorgverlener_koppel = zorgverlener.Zorgverlener_ID)
...
INNER JOIN contract ON (contractueel_contract.Contract_ID = contract.Contract_ID)
Other tips:
Do use table aliases
Don't use unnecessary parentheses
To correct that issue change the order of the joins:
SELECT
czp.*
FROM concern_zorgaanbieder_prijslijst as czp
...
INNER JOIN contract AS C ON contractueel_contract.Contract_ID = contract.Contract_ID
...
INNER JOIN zorgverlener ON c.Zorgverlener_koppel = zorgverlener.Zorgverlener_ID
but now we see that contractueel_contract needs to go above contract and so on it goes.
I believe a more correct sequence of jois is as follows, but there are 2 joins I cannot solve:
SELECT
czp.*
FROM concern_zorgaanbieder_prijslijst AS czp
INNER JOIN prijslijst ON czp.Prijslijst_ID = prijslijst.Prijslijst_ID
INNER JOIN concern ON czp.Concern_ID = concern.Concern_ID
## problems in the next 2 lines, seem to be recursve
INNER JOIN diagnosebereik ON dbc_diagnosebereik.Diagnosebereik_naam = diagnosebereik.Diagnosebereik_naam
INNER JOIN dbc_diagnosebereik ON diagnosebereik.Diagnosebereik_naam = dbc_diagnosebereik.Diagnosebereik_naam
INNER JOIN dbc ON dbc_diagnosebereik.DBC_koppel = dbc.DBC_koppel
INNER JOIN zorgproducten ON dbc.ZP_code = zorgproducten.ZP_code
INNER JOIN zorgproducten_declaratie ON zorgproducten.ZP_code = zorgproducten_declaratie.ZP_code
INNER JOIN declaratie ON zorgproducten_declaratie.Declaratie_code = declaratie.Declaratie_code
INNER JOIN contractueel_decaratie ON declaratie.Declaratie_code = contractueel_decaratie.Declaratie_code
INNER JOIN contractueel ON contractueel_decaratie.Contractueel_ID = contractueel.Contractueel_ID
INNER JOIN contractueel_contract ON contractueel.Contractueel_ID = contractueel_contract.Contract_ID
INNER JOIN contract ON contractueel_contract.Contract_ID = contract.Contract_ID
INNER JOIN zorgverlener ON contract.Zorgverlener_koppel = zorgverlener.Zorgverlener_ID
INNER JOIN zorgaanbieder ON czp.Zorgaanbieder_ID = zorgaanbieder.Zorgaanbieder_ID
INNER JOIN zorgaanbieder AS zorgaanbieder_1 ON zorgverlener.Zorgaanbieder_ID = zorgaanbieder_1.Zorgaanbieder_ID
INNER JOIN zorgverzekeraar ON contract.Zorgverzekeraar_koppel = zorgverzekeraar.Zorgverzekeraar_ID
INNER JOIN concern AS concern_1 ON zorgverzekeraar.Concern_ID = concern_1.Concern_ID
INNER JOIN zorgproducten_declaratie ON zorgproducten.ZP_code = zorgproducten_declaratie.ZP_code
INNER JOIN zorgproductgroepen ON zorgproducten.ZPG_code = zorgproductgroepen.ZPG_code
INNER JOIN diagnosen ON diagnosebereik.Diagnose_ID = diagnosen.Diagnose_ID
INNER JOIN specialisme ON diagnosen.Specialisme_code = specialisme.Specialisme_code
INNER JOIN behandelingen ON dbc.DBC_koppel = behandelingen.DBC_koppel
INNER JOIN cluster ON behandelingen.Cluster_ID = cluster.Cluster_ID
INNER JOIN aanspraak ON behandelingen.Aanspraak_code = aanspraak.Aanspraak_code
INNER JOIN zorgactiviteit_behandelingen ON behandelingen.Behandeling_naam = zorgactiviteit_behandelingen.Behandeling_naam
INNER JOIN zorgactiviteiten ON zorgactiviteit_behandelingen.ZA_code = zorgactiviteiten.ZA_code
INNER JOIN zorgprofielklasse ON zorgactiviteiten.ZPK_code = zorgprofielklasse.ZPK_code

how do create a where clause to return if any of the columns in where cluase have active=1

I have an SQL query like below which has a where clause as WHERE pg.active=1 AND tcg.active=1 AND tpg.active=1,issue right now is that one or all of pg.active tcg.active ,tpg.active is set to 1 at any time,in the case where one of these is not set to 1 query doesn't return anything.
How do I change the where clause to return if any of pg.active tcg.active ,tpg.active is set to 1?
SELECT
..........
FROM software_products_software_images spsi
INNER JOIN software_images si ON si.software_image_id = spsi.software_image_id
INNER JOIN software_products sp ON sp.id = spsi.software_product_id
LEFT JOIN software_products_software_images_testplan_gate tpg ON tpg.software_products_software_images_id = spsi.Id
LEFT JOIN test_suites tp ON tp.id = tpg.testplan_id
LEFT JOIN software_products_software_images_testcase_gate tcg ON tcg.software_products_software_images_id = spsi.Id
LEFT JOIN test_cases tc ON tc.id = tcg.testcase_id
LEFT JOIN test_suites ts ON ts.id = tc.test_suite_id
LEFT JOIN software_products_software_images_percentage_gate pg ON pg.software_products_software_images_id = spsi.Id
...........................
WHERE pg.active=1 AND tcg.active=1 AND tpg.active=1
AND si.software_image='NHSS.QSDK.7.0.1' ORDER BY si.software_image, ts.suite_name
I believe you need to encapsulate the OR part of the WHERE statement in round brackets so that it returns a TRUE on any OR match along with your other conditions.
SELECT
..........
FROM software_products_software_images spsi
INNER JOIN software_images si ON si.software_image_id = spsi.software_image_id
INNER JOIN software_products sp ON sp.id = spsi.software_product_id
LEFT JOIN software_products_software_images_testplan_gate tpg ON tpg.software_products_software_images_id = spsi.Id
LEFT JOIN test_suites tp ON tp.id = tpg.testplan_id
LEFT JOIN software_products_software_images_testcase_gate tcg ON tcg.software_products_software_images_id = spsi.Id
LEFT JOIN test_cases tc ON tc.id = tcg.testcase_id
LEFT JOIN test_suites ts ON ts.id = tc.test_suite_id
LEFT JOIN software_products_software_images_percentage_gate pg ON pg.software_products_software_images_id = spsi.Id
...........................
WHERE (pg.active=1 OR tcg.active=1 OR tpg.active=1)
AND si.software_image='NHSS.QSDK.7.0.1' ORDER BY si.software_image, ts.suite_name

How to join a table with a result field of a condition in MySQL

I have an SQL query where in my SELECT part I have a column which is a result of an IF statement. As you can see 'final_vendor_id' contains the value of ioproductrel.vendorid except when it's value is null or 0, because in this case the value of products.vendor_id is used:
SELECT
IF(ioproductrel.vendorid IS NULL OR ioproductrel.vendorid = 0, products.vendor_id, ioproductrel.vendorid) AS 'final_vendor_id',
account.accountname AS 'account',
salesorder.duedate
FROM
internalorder LEFT JOIN ioproductrel ON internalorder.internalorderid = ioproductrel.internalorderid
LEFT JOIN products ON ioproductrel.productid = products.productid
LEFT JOIN slip_relations ON internalorder.internalorderid = slip_relations.child_crmid
INNER JOIN salesorder ON slip_relations.parent_crmid = salesorder.salesorderid
LEFT JOIN account ON salesorder.accountid = account.accountid
LEFT JOIN account AS acc2 ON acc2.accountid = final_vendor_id
WHERE
internalorder.internalorderid = 8982
I want to join a table based on this 'final_vendor_id', but I just get an error that no field with such a name exists.
If I write the whole IF statement in the JOIN part again, it seems to work but Im not sure if it is safe and Im wondering if is there any simplier way than this:
SELECT
IF(ioproductrel.vendorid IS NULL OR ioproductrel.vendorid = 0, products.vendor_id, ioproductrel.vendorid) AS 'final_vendor_id',
account.accountname AS 'account',
salesorder.duedate
FROM
internalorder LEFT JOIN ioproductrel ON internalorder.internalorderid = ioproductrel.internalorderid
LEFT JOIN products ON ioproductrel.productid = products.productid
LEFT JOIN slip_relations ON internalorder.internalorderid = slip_relations.child_crmid
INNER JOIN salesorder ON slip_relations.parent_crmid = salesorder.salesorderid
LEFT JOIN account ON salesorder.accountid = account.accountid
LEFT JOIN account AS acc2 ON acc2.accountid = IF(ioproductrel.vendorid IS NULL OR ioproductrel.vendorid = 0, products.vendor_id, ioproductrel.vendorid)
WHERE
internalorder.internalorderid = 8982
What if set single quotes in left join section like:
...ON acc2.accountid = 'final_vendor_id'

mysql where not in to left outer join

I have the following query and would like to convert it to using a left outer join instead of a not in to see if it would run faster that way. It's currently taking this query about 40 seconds to run on our database. I'm not familiar enough with using outer joins for this type of thing to convert it myself.
select
c.contact_id as contact_id,
c.orgid as organization_id,
c.first_name as first_name,
c.last_name as last_name,
a.address_state as state
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
where a.address_state = 'OH'
and (c.orgid = 45 or c.orgid = 55)
and c.contact_id NOT IN (
select pc.contact_id
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
inner join cnx_contact_group_participant as gp on c.contact_id = gp.contact_id
inner join cnx_contact_participant_role as cr on gp.participant_role_uid = cr.participant_role_uid
inner join cnx_contact_group as cg on gp.group_uid = cg.group_uid
inner join cnx_contact_group_participant as pgp on cg.primary_participant_uid = pgp.participant_uid
inner join cnx_contact as pc on pgp.contact_id = pc.contact_id
where (c.orgid = 45 or c.orgid = 55)
and cr.name = 'Applicant'
);
select
c.columns
from cnx_contact as c
inner join cnx_address as a on c.home_address_uid = a.address_uid
LEFT JOIN
(Subquery goes here) x
ON x.contact _id = c.contact_id
where a.participant_state = 'OH'
and c.orgid IN(45,55)
and x.contact_id IS NULL;

MS-Access Joining 2 Subqueries

Need a little help with subqueries
If I have a 1 query like this:
SELECT Learner.Learner_Id, Max(LearnerEmploymentStatus.DateEmpStatApp) AS LatestEmpDate, Learner.LearnRefNumber, Learner.FamilyName, Learner.GivenNames, EmploymentStatusMonitoring.ESMType
FROM (Learner LEFT JOIN LearnerEmploymentStatus ON LearnerEmploymentStatus.Learner_Id = LearnerEmploymentStatus.Learner_Id) LEFT JOIN EmploymentStatusMonitoring ON LearnerEmploymentStatus.LearnerEmploymentStatus_Id = EmploymentStatusMonitoring.LearnerEmploymentStatus_Id
WHERE EmploymentStatusMonitoring.ESMType="BSI"
GROUP BY Learner.Learner_Id, Learner.LearnRefNumber, Learner.FamilyName, Learner.GivenNames, EmploymentStatusMonitoring.ESMType
...and another like this:
SELECT Learner.Learner_Id, LearnerEmploymentStatus.DateEmpStatApp, EmploymentStatusMonitoring.ESMCode
FROM (Learner LEFT JOIN LearnerEmploymentStatus ON Learner.Learner_Id = LearnerEmploymentStatus.Learner_Id) LEFT JOIN EmploymentStatusMonitoring ON LearnerEmploymentStatus.LearnerEmploymentStatus_Id = EmploymentStatusMonitoring.LearnerEmploymentStatus_Id
...and I wanted to do a join between the 2 queries (LEFT JOIN on the common Learner_Id and LatestEmpDate / DateEmpStatApp fields), how would I go about doing all this work in a single query where the 2 queries above would be subqueries?
My attempt below is not being accepted (JOIN expression not supported):
SELECT sQ1.Learner_Id, sQ1.LearnRefNumber, sQ1.FamilyName, sQ1.GivenNames, sQ1.LatestEmpDate, sQ1.ESMType, sQ2.ESMCode
FROM
(SELECT Learner.Learner_Id, Max(LearnerEmploymentStatus.DateEmpStatApp) AS LatestEmpDate, Learner.LearnRefNumber, Learner.FamilyName, Learner.GivenNames, EmploymentStatusMonitoring.ESMType
FROM (Learner LEFT JOIN LearnerEmploymentStatus ON LearnerEmploymentStatus.Learner_Id = LearnerEmploymentStatus.Learner_Id) LEFT JOIN EmploymentStatusMonitoring ON LearnerEmploymentStatus.LearnerEmploymentStatus_Id = EmploymentStatusMonitoring.LearnerEmploymentStatus_Id
WHERE EmploymentStatusMonitoring.ESMType="BSI"
GROUP BY Learner.Learner_Id, Learner.LearnRefNumber, Learner.FamilyName, Learner.GivenNames, EmploymentStatusMonitoring.ESMType) As sQ1
LEFT JOIN
(SELECT Learner.Learner_Id, LearnerEmploymentStatus.DateEmpStatApp, EmploymentStatusMonitoring.ESMCode
FROM (Learner LEFT JOIN LearnerEmploymentStatus ON Learner.Learner_Id = LearnerEmploymentStatus.Learner_Id) LEFT JOIN EmploymentStatusMonitoring ON LearnerEmploymentStatus.LearnerEmploymentStatus_Id = EmploymentStatusMonitoring.LearnerEmploymentStatus_Id) As sQ2
ON (sQ1.Learner_Id = sQ2.Learner_Id) AND (sQ1.LatestEmpDate = sQ2.DateEmpStatApp);
Would something like this get you what you want...?
SELECT l.Learner_Id, d.LatestEmpDate, l.LearnRefNumber, l.FamilyName, l.GivenNames, m.ESMType, m.ESMCode
FROM ((Learner AS l
LEFT JOIN (
SELECT s.Learner_Id, MAX(s.DateEmpStatApp) AS LatestEmpDate
FROM LearnerEmploymentStatus AS s
GROUP BY s.Learner_Id) AS d ON d.Learner_Id = l.Learner_Id)
LEFT JOIN LearnerEmploymentStatus AS ls ON (ls.Learner_Id = d.Learner_Id) AND (ls.DateEmpStatApp = d.LatestEmpDate))
LEFT JOIN EmploymentStatusMonitoring AS m ON m.LearnerEmploymentStatus_Id = ls.LearnerEmploymentStatus_Id
WHERE m.ESMType = 'BSI'
Assumes the same learner won't have the same DateEmpStatApp twice, which may or not be valid.