I have a SQL Statement like this:
select
b.ActivityRecordId, b.ActivityName, b.ActivityDetail,
b.CustomerId, e.CustomerName,
b.JobStatusId, c.JobStatusName, b.EstimateStartDate,
b.EstimateFinishDate, b.StartedDateTime, b.FinishedDateTime,
a.ActivityRecordProgressId, a.CustomerContactId,
Concat(d.FirstName, ' ', d.MiddleName, ' ', d.LastName) as fullName,
a.Started, a.Finished, a.ActivityDescription,
g.ActivityTypeId, g.ActivityTypeName, a.ActivitySubTypeId, f.ActivitySubTypeName
from
ActivityRecordProgress a
right join
ActivityRecord b on a.ActivityRecordId = b.ActivityRecordId
left join
ActivitySubType f on a.ActivitySubTypeId = f.ActivitySubTypeId
left join
ActivityType g on f.ActivityTypeId = g.ActivityTypeId
left join
CustomerContact d on a.CustomerContactId = d.CustomerContactId
inner join
JobStatus c on b.JobStatusId = c.JobStatusId
inner join
Customer e on b.CustomerId = e.CustomerId
Then I tried to convert it to Linq:
var obj = (from a in _db.ActivityRecords
join b in _db.ActivityRecordProgresses on a.ActivityRecordId equals b.ActivityRecordId into ab
from p in ab.DefaultIfEmpty()
join c in _db.Customers on a.CustomerId equals c.CustomerId
join e in _db.CustomerContacts on c.CustomerId equals e.CustomerId
join d in _db.JobStatuses on a.JobStatusId equals d.JobStatusId
join f in _db.ActivitySubTypes on p.ActivitySubTypeId equals f.ActivitySubTypeId
join g in _db.ActivityTypes on f.ActivitySubTypeId equals g.ActivityTypeId
select new OutstandingActivityViewModel {
ActivityRecordId = p.ActivityRecordId,
ActivityName = a.ActivityName,
ActivityDetail = a.ActivityDetail,
CustomerId = a.CustomerId,
CustomerName = c.CustomerName,
JobStatusId = a.JobStatusId,
JobStatusName = d.JobStatusName,
EstimateStartDate = a.EstimateStartDate,
StartedDateTime = a.StartedDateTime,
EstimateFinishDateTime = a.EstimateFinishDate,
FinishedDateTime = a.FinishedDateTime,
FirstName = e.FirstName, MiddleName = e.MiddleName, LastName = e.LastName,
Started = p.Started, Finished = p.Finished,
ActivityTypeName = g.ActivityTypeName, ActivitySubTypeName = f.ActivitySubTypeName,
ActivityDescription = p.ActivityDescription
}).ToListAsync();
But the result is not the same. The SQL result is the right one. It only 4 records. But in Linq, it appears 6 records. I'm sure I did something wrong with the linq syntax.
Can anyone show me where the mistake in my syntax is?
Really appreciated - thank you.
Thanks for commenting my question. It was very useful.
Finally I found the answer after trial and error using SQL generated. Below is the answer for the Linq syntax:
var obj = (from a in _db.ActivityRecords
join b in _db.ActivityRecordProgresses on a.ActivityRecordId equals b.ActivityRecordId into leftsatu
from leftkesatu in leftsatu.DefaultIfEmpty()
join c in _db.ActivitySubTypes on leftkesatu.ActivitySubTypeId equals c.ActivitySubTypeId into leftdua
from leftkedua in leftdua.DefaultIfEmpty()
join d in _db.ActivityTypes on leftkedua.ActivitySubTypeId equals d.ActivityTypeId into lefttiga
from leftketiga in lefttiga.DefaultIfEmpty()
join e in _db.CustomerContacts on leftkesatu.CustomerContactId equals e.CustomerContactId into leftempat
from leftkeempat in leftempat.DefaultIfEmpty()
join f in _db.JobStatuses on a.JobStatusId equals f.JobStatusId
join g in _db.Customers on a.CustomerId equals g.CustomerId
select new OutstandingActivityViewModel
{
ActivityRecordId = a.ActivityRecordId,
ActivityName = a.ActivityName,
ActivityDetail = a.ActivityDetail,
CustomerId = a.CustomerId,
CustomerName = g.CustomerName,
JobStatusId = a.JobStatusId,
JobStatusName = f.JobStatusName,
EstimateStartDate = a.EstimateStartDate,
StartedDateTime = a.StartedDateTime,
EstimateFinishDateTime = a.EstimateFinishDate,
FinishedDateTime = a.FinishedDateTime,
FirstName = leftkeempat.FirstName,
MiddleName = leftkeempat.MiddleName,
LastName = leftkeempat.LastName,
Started = leftkesatu.Started,
Finished = leftkesatu.Finished,
ActivityTypeName = leftketiga.ActivityTypeName,
ActivitySubTypeName = leftkedua.ActivitySubTypeName,
ActivityDescription = leftkesatu.ActivityDescription
}
);
It will generate SQL like:
SELECT [a].[ActivityRecordId], [a].[ActivityName], [a].[ActivityDetail], [a].[CustomerId], [c0].[CustomerName], [a].[JobStatusId], [j].[JobStatusName],
[a].[EstimateStartDate], [a].[StartedDateTime], [a].[EstimateFinishDate] AS [EstimateFinishDateTime], [a].[FinishedDateTime],
[c].[FirstName], [c].[MiddleName], [c].[LastName],
[a0].[Started], [a0].[Finished], [a2].[ActivityTypeName], [a1].[ActivitySubTypeName], [a0].[ActivityDescription]
FROM [ActivityRecord] AS [a]
LEFT JOIN [ActivityRecordProgress] AS [a0] ON [a].[ActivityRecordId] = [a0].[ActivityRecordId]
LEFT JOIN [ActivitySubType] AS [a1] ON [a0].[ActivitySubTypeId] = [a1].[ActivitySubTypeId]
LEFT JOIN [ActivityType] AS [a2] ON [a1].[ActivitySubTypeId] = [a2].[ActivityTypeId]
LEFT JOIN [CustomerContact] AS [c] ON [a0].[CustomerContactId] = [c].[CustomerContactId]
INNER JOIN [JobStatus] AS [j] ON [a].[JobStatusId] = [j].[JobStatusId]
INNER JOIN [Customer] AS [c0] ON [a].[CustomerId] = [c0].[CustomerId]
I have a query according to the :
SELECT
tblDefinition.TopsisType, tblTemplate.tType, tblEvaluationFormCategory.Title AS EvaluationCategory,
CASE tType WHEN 1 THEN N'2'
ELSE N'1' END ProcessType,
tblDefinition.Description, tblDefinition.TemplateID, 1 Destinition
FROM tblTemplate INNER JOIN
tblEvaluationFormCategory ON tblTemplate.CategoryID = tblEvaluationFormCategory.ID INNER JOIN
tblEFQMAlternative INNER JOIN
tblDefinition ON ([tblEFQMAlternative].[TopsisID] = [tblDefinition].[TopsisID] AND [tblEFQMAlternative].[CustomerID] = [tblDefinition].[CustomerID]) INNER JOIN
tblGroupMembers ON ([tblDefinition].[TopsisID] = [tblGroupMembers].[TopsisID]
AND tblDefinition.CustomerID =
tblGroupMembers.CustomerID) ON tblTemplate.TemplateID = tblDefinition.TemplateID
INNER JOIN
tblTerm ON tblDefinition.TermGrant = tblTerm.Title
WHERE (tblTerm.ID = 20) AND (tblGroupMembers.UserID = 558)
GROUP BY tblDefinition.TopsisType, tblTemplate.tType, tblEvaluationFormCategory.Title,
tblDefinition.Description, tblDefinition.TemplateID
when i convert to linq, then error to :
Field [([tblDefinition].[TopsisID] = [tblGroupMembers]].[[TopsisID] AND tblDefinition.CustomerID = tblGroupMembers.CustomerID) ON tblTemplate.TemplateID] not found in the current Data Context.
What should I do?
I wrote a query that does an inner join of two subqueries. The first subquery has an alias of "SRC" and the other has an alias of "DEST". What I want to do is update some fields in the table NomineeActionLegislatorVoteDetail (part of DEST subquery) with values from the table Nominee_Committee_Vote (part of SRC subquery). It souds easy but I just cannot figure out how to do it. Does anyone have any suggestions? Any help would be appreciated.
Here is the query I wrote:
select *
from (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC
inner join (
select votedetail.*
from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
Can you insert the update in front of the sub queries
UPDATE NomineeActionLegislatorVoteDetail
SET NomineeActionLegislatorVoteDetail.COLUMNNAME = src.VALUE
--SubQueriesBelow
from
(select ncv.*, na.NomineeActionId, l.LegislatorId from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId) SRC
inner join
(select votedetail.* from azleg..NomineeActionLegislatorVoteDetail votedetail
inner join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId) DEST on
SRC.agency_id = DEST.x_agency_id and
SRC.position_id = DEST.x_position_id and
SRC.nominee_id = DEST.x_nominee_id and
SRC.received_date = DEST.x_received_date and
SRC.session_id = DEST.x_session_id and
SRC.committee_id = DEST.x_committee_id and
SRC.member_id = DEST.x_member_id
where SRC.NomineeActionId <> DEST.NomineeActionId
OR SRC.LegislatorId <> DEST.LegislatorId
OR SRC.Vote <> DEST.Vote
It looks like the update is on a table in the sub query so it could be re factored to have one subquery
I've adjusted the lay-out of your query a bit to disclose better where subqueries start and end. In your DEST subquery, you join NomineeAction but you don't select any columns from it, so it only filters rows from NomineeActionLegislatorVoteDetail for which no NomineeAction exists. So really you wanna be updating and joining on columns from NomineeActionLegislatorVoteDetail exclusively. Based on that, I would write the update query like so:
update votedetail set
votedetail.SomeColumn = SomeValue,
votedetail.SomeOtherColumn = SomeOtherValue
from azleg..NomineeActionLegislatorVoteDetail votedetail
join azleg..NomineeAction nom_action on
votedetail.NomineeActionId = nom_action.NomineeActionId
join (
select ncv.*,
na.NomineeActionId,
l.LegislatorId
from ongoing..Nominee_Committee_Vote ncv
inner join azleg..NomineeAction na on
ncv.session_id = na.x_session_id and
ncv.committee_id = na.x_committee_id and
ncv.agency_id = na.x_agency_id and
ncv.position_id = na.x_position_id and
ncv.nominee_id = na.x_nominee_id and
ncv.received_date = na.x_received_date
inner join status..session s on
ncv.session_id = s.session_id
inner join azleg..Legislator l on
ncv.member_id = l.x_member_id and
s.legislature = l.LegislatureId
) SRC on
SRC.agency_id = votedetail.x_agency_id and
SRC.position_id = votedetail.x_position_id and
SRC.nominee_id = votedetail.x_nominee_id and
SRC.received_date = votedetail.x_received_date and
SRC.session_id = votedetail.x_session_id and
SRC.committee_id = votedetail.x_committee_id and
SRC.member_id = votedetail.x_member_id
where SRC.NomineeActionId <> votedetail.NomineeActionId
OR SRC.LegislatorId <> votedetail.LegislatorId
OR SRC.Vote <> votedetail.Vote
Trying to update the fact table with late coming dimension data. See Code below
UPDATE FactVehicleStock
SET
FactVehicleStock.[TOL_BidDateTime] = B.Bid_Date_and_Time,
FactVehicleStock.[TOL_AuctionDate] = B.Date_opened_for_tender,
FactVehicleStock.[TOL_OriginalLoadDate] = B.Original_Load_date,
FactVehicleStock.[TOL_ServiceHistory] = B.Service_History,
FactVehicleStock.[TOL_ReservedPrice] = B.Reserve_price,
FactVehicleStock.[TOL_BidPrice] = B.Bid_Price,
FactVehicleStock.[TOL_OriginalReservedPrice] = B.Original_Reserve_Price,
FactVehicleStock.[TOL_NoOfTimesReloaded] = B.Number_of_times_reloaded
FROM BMR_DWH.dbo.FactVehicleStock as A
INNER JOIN BMR_STAGE.dbo.STG_Traders_Online as B
ON A.StockbookNumber = B.Stock_Number
INNER JOIN BMR_DWH.[dbo].[DimDealership] as C
ON A.DEALERSHIP_KEY IN (SELECT Distinct [DEALERSHIP_KEY]
FROM BMR_DWH.[dbo].[DimDealership]
INNER JOIN [BMR_STAGE].[dbo].[STG_Traders_Online] E
ON LTRIM(RTRIM(C.MOLNUMBER)) = LTRIM(RTRIM(E.MOL_Number))
)
Try to use the right UPDATE SELECT Syntaxe.
If you look at the code I did, I had to change a bit your query to do the joins. See if it fits to you.
UPDATE BMR_DWH.dbo.FactVehicleStock as a
INNER JOIN BMR_STAGE.dbo.STG_Traders_Online as B
ON A.StockbookNumber = B.Stock_Number
INNER JOIN
(SELECT Distinct [DEALERSHIP_KEY]
FROM BMR_DWH.[dbo].[DimDealership] as C
INNER JOIN [BMR_STAGE].[dbo].[STG_Traders_Online] E
ON LTRIM(RTRIM(C.MOLNUMBER)) = LTRIM(RTRIM(E.MOL_Number)) ) D
ON A.DEALERSHIP_KEY = D.DEALERSHIP_KEY
SET
FactVehicleStock.[TOL_BidDateTime] = B.Bid_Date_and_Time,
FactVehicleStock.[TOL_AuctionDate] = B.Date_opened_for_tender,
FactVehicleStock.[TOL_OriginalLoadDate] = B.Original_Load_date,
FactVehicleStock.[TOL_ServiceHistory] = B.Service_History,
FactVehicleStock.[TOL_ReservedPrice] = B.Reserve_price,
FactVehicleStock.[TOL_BidPrice] = B.Bid_Price,
FactVehicleStock.[TOL_OriginalReservedPrice] = B.Original_Reserve_Price,
FactVehicleStock.[TOL_NoOfTimesReloaded] = B.Number_of_times_reloaded
Ok, so this is what i'm stuck with.
Full size
SELECT dbo.InstellingGegevens.INST_SUBTYPE, dbo.InstellingGegevens.INST_BRON, dbo.InstellingGegevens.INST_INSTELLINGSNUMMER,
dbo.InstellingGegevens.INST_NAAM, dbo.InstellingGegevens.INST_KORTENAAM, dbo.InstellingGegevens.INST_VESTIGINGSNAAM,
dbo.InstellingGegevens.INST_ROEPNAAM, dbo.InstellingGegevens.INST_STATUUT, dbo.InstellingGegevens.ONDERWIJSNIVEAU_REF,
dbo.InstellingGegevens.ONDERWIJSSOORT_REF, dbo.InstellingGegevens.DATUM_TOT, dbo.InstellingGegevens.DATUM_VAN,
dbo.InstellingGegevens.VERBOND_REF, dbo.InstellingGegevens.VSKO_LID, dbo.InstellingGegevens.NET_REF, dbo.Instellingen.Inst_ID, dbo.Instellingen.INST_TYPE,
dbo.Instellingen.INST_REF, dbo.Instellingen.INST_LOC_REF, dbo.Instellingen.INST_LOCNR, dbo.Instellingen.Opt_KalStandaard, dbo.InstellingTelecom.INST_TEL,
dbo.InstellingTelecom.INST_FAX, dbo.InstellingTelecom.INST_EMAIL, dbo.InstellingTelecom.INST_WEB, dbo.InstellingAdressen.SOORT,
dbo.InstellingAdressen.STRAAT, dbo.InstellingAdressen.POSTCODE, dbo.InstellingAdressen.GEMEENTE, dbo.InstellingAdressen.GEM_REF,
dbo.InstellingAdressen.FUSIEGEM_REF, dbo.InstellingAdressen.FUSIEGEM, dbo.InstellingAdressen.ALFA_G, dbo.InstellingAdressen.PROVINCIE,
dbo.InstellingAdressen.BISDOM, dbo.InstellingAdressen.ARRONDISSEMENT, dbo.InstellingAdressen.GEWEST, dbo.InstellingLogin.Inst_Gebruikersnaam,
dbo.InstellingLogin.Inst_Concode, dbo.InstellingLogin.Inst_DirCode, dbo.InstellingLogin.DOSSNR, dbo.InstellingLogin.Instelling_ID,
dbo.InstellingContPersDirecteurs.AANSPREKING, dbo.InstellingContPersDirecteurs.CONTACTPERSOON, dbo.InstellingContPersDirecteurs.FUNCTIE
FROM dbo.InstellingGegevens RIGHT OUTER JOIN
dbo.Instellingen ON dbo.InstellingGegevens.INST_TYPE = dbo.Instellingen.INST_TYPE AND dbo.InstellingGegevens.INST_REF = dbo.Instellingen.INST_REF AND
dbo.InstellingGegevens.INST_LOC_REF = dbo.Instellingen.INST_LOC_REF AND
dbo.InstellingGegevens.INST_LOCNR = dbo.Instellingen.INST_LOCNR LEFT OUTER JOIN
dbo.InstellingTelecom ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingTelecom.INST_TYPE AND
dbo.InstellingGegevens.INST_REF = dbo.InstellingTelecom.INST_REF AND
dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingTelecom.INST_LOC_REF LEFT OUTER JOIN
dbo.InstellingAdressen ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingAdressen.INST_TYPE AND
dbo.InstellingGegevens.INST_REF = dbo.InstellingAdressen.INST_REF AND
dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingAdressen.INST_LOC_REF LEFT OUTER JOIN
dbo.InstellingLogin ON dbo.InstellingLogin.Inst_InstellingIKONType = dbo.Instellingen.INST_TYPE AND
dbo.InstellingLogin.Inst_InstellingIKON_REF = dbo.Instellingen.INST_REF AND dbo.InstellingLogin.Inst_Loc_REF = dbo.Instellingen.INST_LOC_REF AND
dbo.InstellingLogin.Inst_Loc_Nr = dbo.Instellingen.INST_LOCNR LEFT OUTER JOIN
dbo.InstellingContPersDirecteurs ON dbo.InstellingGegevens.INST_TYPE = dbo.InstellingContPersDirecteurs.INST_TYPE AND
dbo.InstellingGegevens.INST_REF = dbo.InstellingContPersDirecteurs.INST_REF AND
dbo.InstellingGegevens.INST_LOC_REF = dbo.InstellingContPersDirecteurs.INST_LOC_REF
WHERE (NOT (dbo.InstellingLogin.Inst_InstellingIKON_REF IS NULL))
So here is the problem:
the 'should be' PK is a 1 varchar 3 int's key. for every key there is supposed to be 1 row in each of the tables which you can see in the image. the 'parent' of those keys is the table Instellingen. This table is generated with a distinct select of InstellingenLogin
the real problem is that there are about 10 doubles in InstellingenLogin (of about 5k records) and because of this, some rows return double in the view, with only the columns of InstellingLogin different.
what i want is that if there are 2 or more rows in InstellingLogin with the same key, that only 1 will show (the first one,... doenst matter which one, just 1 will do).
in short that means that for every record in Instellingen i want 1 record in this view.
is there any way to do that?
I'm a bit confused but I think the answer below should illustrate how to acheive what you need:
SELECT * FROM Instellingen as i
CROSS APPLY
(
SELECT TOP (1) * FROM InstellingLogin as il
WHERE i.INST_LOC_REF = il.Inst_Loc_REF
and i.INST_LOCNR=il.Inst_Loc_Nr
and i.INST_REF=il.Inst_InstellingIKON_REF
and i.INST_TYPE=il.Inst_InstellingIKONType
order by il.Datum_tot
) la
This will basically join on Instellingen and InstellingenLogin but only on the first record found
You can use DENSE_RANK to Arbitrarily select a row. Basically create a CTE that ranks the instellinglogin and then only select the one with a Rank of 1. The tricky bit is that you have a left join to instellinglogin so you'll need to do the inner join inside the left join like so. Also I kept the Join condition as the the columns to partition. This may not be correct.
LEFT OUTER JOIN (dbo.instellinglogin
INNER JOIN unique_login
ON dbo.instellinglogin.inst_instellingikontype =
unique_login .inst_instellingikontype
AND dbo.instellinglogin.inst_instellingikon_ref =
unique_login.inst_instellingikon_ref
AND dbo.instellinglogin.inst_loc_ref =
unique_login.inst_loc_ref
AND dbo.instellinglogin.inst_loc_nr =
unique_login.inst_loc_nr
AND unique_login.therank = 1 )
ON dbo.instellinglogin.inst_instellingikontype =
dbo.instellingen.inst_type
AND dbo.instellinglogin.inst_instellingikon_ref =
dbo.instellingen.inst_ref
AND dbo.instellinglogin.inst_loc_ref = dbo.instellingen.inst_loc_ref
AND dbo.instellinglogin.inst_loc_nr = dbo.instellingen.inst_locnr
Here's the complete SQL Below
WITH unique_login
AS (SELECT instellinglogin.inst_instellingikontype,
instellinglogin.inst_instellingikon_ref,
instellinglogin.inst_loc_ref,
instellinglogin.inst_loc_nr,
Dense_rank() OVER (ORDER BY
instellinglogin.inst_instellingikontype,
instellinglogin.inst_instellingikon_ref,
instellinglogin.inst_loc_ref,
instellinglogin.inst_loc_nr) AS therank)
SELECT dbo.instellinggegevens.inst_subtype,
dbo.instellinggegevens.inst_bron,
dbo.instellinggegevens.inst_instellingsnummer,
dbo.instellinggegevens.inst_naam,
dbo.instellinggegevens.inst_kortenaam,
dbo.instellinggegevens.inst_vestigingsnaam,
dbo.instellinggegevens.inst_roepnaam,
dbo.instellinggegevens.inst_statuut,
dbo.instellinggegevens.onderwijsniveau_ref,
dbo.instellinggegevens.onderwijssoort_ref,
dbo.instellinggegevens.datum_tot,
dbo.instellinggegevens.datum_van,
dbo.instellinggegevens.verbond_ref,
dbo.instellinggegevens.vsko_lid,
dbo.instellinggegevens.net_ref,
dbo.instellingen.inst_id,
dbo.instellingen.inst_type,
dbo.instellingen.inst_ref,
dbo.instellingen.inst_loc_ref,
dbo.instellingen.inst_locnr,
dbo.instellingen.opt_kalstandaard,
dbo.instellingtelecom.inst_tel,
dbo.instellingtelecom.inst_fax,
dbo.instellingtelecom.inst_email,
dbo.instellingtelecom.inst_web,
dbo.instellingadressen.soort,
dbo.instellingadressen.straat,
dbo.instellingadressen.postcode,
dbo.instellingadressen.gemeente,
dbo.instellingadressen.gem_ref,
dbo.instellingadressen.fusiegem_ref,
dbo.instellingadressen.fusiegem,
dbo.instellingadressen.alfa_g,
dbo.instellingadressen.provincie,
dbo.instellingadressen.bisdom,
dbo.instellingadressen.arrondissement,
dbo.instellingadressen.gewest,
dbo.instellinglogin.inst_gebruikersnaam,
dbo.instellinglogin.inst_concode,
dbo.instellinglogin.inst_dircode,
dbo.instellinglogin.dossnr,
dbo.instellinglogin.instelling_id,
dbo.instellingcontpersdirecteurs.aanspreking,
dbo.instellingcontpersdirecteurs.contactpersoon,
dbo.instellingcontpersdirecteurs.functie
FROM dbo.instellinggegevens
RIGHT OUTER JOIN dbo.instellingen
ON dbo.instellinggegevens.inst_type = dbo.instellingen.inst_type
AND dbo.instellinggegevens.inst_ref = dbo.instellingen.inst_ref
AND dbo.instellinggegevens.inst_loc_ref =
dbo.instellingen.inst_loc_ref
AND dbo.instellinggegevens.inst_locnr = dbo.instellingen.inst_locnr
LEFT OUTER JOIN dbo.instellingtelecom
ON dbo.instellinggegevens.inst_type = dbo.instellingtelecom.inst_type
AND dbo.instellinggegevens.inst_ref = dbo.instellingtelecom.inst_ref
AND dbo.instellinggegevens.inst_loc_ref =
dbo.instellingtelecom.inst_loc_ref
LEFT OUTER JOIN dbo.instellingadressen
ON dbo.instellinggegevens.inst_type = dbo.instellingadressen.inst_type
AND dbo.instellinggegevens.inst_ref =
dbo.instellingadressen.inst_ref
AND dbo.instellinggegevens.inst_loc_ref =
dbo.instellingadressen.inst_loc_ref
LEFT OUTER JOIN (dbo.instellinglogin
INNER JOIN unique_login
ON dbo.instellinglogin.inst_instellingikontype =
unique_login .inst_instellingikontype
AND dbo.instellinglogin.inst_instellingikon_ref =
unique_login.inst_instellingikon_ref
AND dbo.instellinglogin.inst_loc_ref =
unique_login.inst_loc_ref
AND dbo.instellinglogin.inst_loc_nr =
unique_login.inst_loc_nr
AND unique_login.therank = 1 )
ON dbo.instellinglogin.inst_instellingikontype =
dbo.instellingen.inst_type
AND dbo.instellinglogin.inst_instellingikon_ref =
dbo.instellingen.inst_ref
AND dbo.instellinglogin.inst_loc_ref = dbo.instellingen.inst_loc_ref
AND dbo.instellinglogin.inst_loc_nr = dbo.instellingen.inst_locnr
LEFT OUTER JOIN dbo.instellingcontpersdirecteurs
ON dbo.instellinggegevens.inst_type =
dbo.instellingcontpersdirecteurs.inst_type
AND dbo.instellinggegevens.inst_ref =
dbo.instellingcontpersdirecteurs.inst_ref
AND dbo.instellinggegevens.inst_loc_ref =
dbo.instellingcontpersdirecteurs.inst_loc_ref
WHERE ( NOT ( dbo.instellinglogin.inst_instellingikon_ref IS NULL ) )
You need to wrap InstellingenLogin in some kind of aggregate to remove the duplicates and then join to the result - you can do this with a subquery. You could do a GROUP BY with MIN() or MAX() to pick a value or you could do ROW_NUMBER() OVER (ORDER BY some_criteria PARTIION BY your_key) and pick the first row.
Also, I recommend using aliases on your tables - makes it far more readable
WITH UniqueLogins AS (
-- How to pick Inst_Gebruikersnaam, Inst_Concode, Inst_DirCode, DOSSNR, Instelling_ID, InstellingIKONType, Inst_Loc_REF, Inst_Loc_Nr, Inst_InstellingIKON_REF
SELECT key columns, MIN(non key column), MIN(non key column), MIN(non key column)
FROM dbo.InstellingLogin
GROUP BY key columns
)
SELECT G.INST_SUBTYPE, G.INST_BRON, G.INST_INSTELLINGSNUMMER,
G.INST_NAAM, G.INST_KORTENAAM, G.INST_VESTIGINGSNAAM,
G.INST_ROEPNAAM, G.INST_STATUUT, G.ONDERWIJSNIVEAU_REF,
G.ONDERWIJSSOORT_REF, G.DATUM_TOT, G.DATUM_VAN,
G.VERBOND_REF, G.VSKO_LID, G.NET_REF, I.Inst_ID, I.INST_TYPE,
I.INST_REF, I.INST_LOC_REF, I.INST_LOCNR, I.Opt_KalStandaard, T.INST_TEL,
T.INST_FAX, T.INST_EMAIL, T.INST_WEB, A.SOORT,
A.STRAAT, A.POSTCODE, A.GEMEENTE, A.GEM_REF,
A.FUSIEGEM_REF, A.FUSIEGEM, A.ALFA_G, A.PROVINCIE,
A.BISDOM, A.ARRONDISSEMENT, A.GEWEST, UniqueLogins.Inst_Gebruikersnaam,
UniqueLogins.Inst_Concode, UniqueLogins.Inst_DirCode, UniqueLogins.DOSSNR, UniqueLogins.Instelling_ID,
CPD.AANSPREKING, CPD.CONTACTPERSOON, CPD.FUNCTIE
FROM dbo.InstellingGegevens AS G RIGHT OUTER JOIN
dbo.Instellingen AS I ON G.INST_TYPE = I.INST_TYPE AND G.INST_REF = I.INST_REF AND
G.INST_LOC_REF = I.INST_LOC_REF AND
G.INST_LOCNR = I.INST_LOCNR LEFT OUTER JOIN
dbo.InstellingTelecom AS T ON G.INST_TYPE = T.INST_TYPE AND
G.INST_REF = T.INST_REF AND
G.INST_LOC_REF = T.INST_LOC_REF LEFT OUTER JOIN
dbo.InstellingAdressen AS A ON G.INST_TYPE = A.INST_TYPE AND
G.INST_REF = A.INST_REF AND
G.INST_LOC_REF = A.INST_LOC_REF LEFT OUTER JOIN
UniqueLogins ON UniqueLogins.Inst_InstellingIKONType = I.INST_TYPE AND
UniqueLogins.Inst_InstellingIKON_REF = I.INST_REF AND UniqueLogins.Inst_Loc_REF = I.INST_LOC_REF AND
UniqueLogins.Inst_Loc_Nr = I.INST_LOCNR LEFT OUTER JOIN
dbo.InstellingContPersDirecteurs AS CPD ON G.INST_TYPE = CPD.INST_TYPE AND
G.INST_REF = CPD.INST_REF AND
G.INST_LOC_REF = CPD.INST_LOC_REF
WHERE (NOT (UniqueLogins.Inst_InstellingIKON_REF IS NULL))
Or you could substitute the IntellingLogin table in the query with a derived table such as:
(SELECT RN = row_number() over
(partition by INST_LOC_REF,
INST_LOCNR, INST_REF, INST_TYPE order
by Datum_tot) , * From
InstellingLogin) A
and add in the join condition: A.RN = 1