Structured query language Join query - sql-server

I am new to SQL.Is this a correct join for multiple tables.
select * from [dbo].[Quotes] Q ,[dbo].[Invoices] I ,[dbo].[Receipts] R ,
[dbo].[QuoteLines] QL where QL.QuoteID = Q.ID AND I.QuoteID = Q.ID
AND R.QuoteID = Q.ID AND QL.Amount = 336.47 and QL.TravelType = 'International' and QL.Type = 'Accommodation'

Your question
Is this a correct join for multiple tables
Should be answered with No... It might work as expected, but this way of joining is outdated for centuries.
Your approach names all tables comma separated. This would lead to a huge cartesian product, a combination of each row with each row. The following WHERE clause makes sure, that you will get the needed/related rows and columns only...
Not knowing your structure this is a blind flight, but I think you are looking for something like this:
select *
from [dbo].[Quotes] Q
inner join [dbo].[QuoteLines] QL on Q.ID=QL.QuoteID
inner join [dbo].[Invoices] I on I.QuoteID=Q.ID
inner join [dbo].[Receipts] R on R.QuoteID=Q.ID
where QL.Amount = 336.47
and QL.TravelType = 'International'
and QL.[Type] = 'Accommodation';
You might want to change inner to left in cases, where not each row has a corresponding row on the other side.

Try this:-
Select table1.ID ,table1.Name
from Table1
inner join Table2 on Table1 .ID =Table2 .ID
inner join Table3 on table2.ID=Table3 .ID
where table1.Name = Table3.Name

Related

SQL Server - using Over/Partition By in complex query

We have many complex queries which involve a lot of columns and joins (see the example below) that are implemented as views.
In some cases these queries return duplicate rows which then have to be programmatically removed by the consuming app. Therefore, we would like to enhance the SQL query to eliminate the duplicates, and speed up the retrieval process.
I know that I can use OVER / PARTITION BY logic to do this, but I am not sure of how to modify the queries to obtain a working syntax.
Here is an example:
SELECT
Main.MfgOrder.OrderNumber,
Main.MfgOrder.DesignBOMID,
Main.Design_Plant.PlantID,
Main.MfgOrder_Operation.OrderOpID,
Main.MfgOrder_Operation.DesignOpID,
Main.MfgOrder_Operation.OpSeq,
Main.MfgOrder_Operation.Description,
Main.MfgOrder_Operation.CompletionStatus,
Main.MfgOrder__Shift.OrderShiftID,
Main.MfgOrder__Shift.WorkCenterMachineID,
Main.MfgOrder___Event.OrderEventID,
Main.MfgOrder____Reel.OrderReelID,
Main.MfgOrder____Reel.ReelNumber,
Main.MfgOrder____Reel.Location,
Main.MfgOrder____Reel.Test_Status AS Test_Status_Reel,
Main.MfgOrder____Reel.Test_Disposition AS Test_Disposition_Reel,
Main.MfgOrder____Reel.LabReleased,
Main.MfgOrder____Reel.ShipReelsBypassSet,
Main.MfgOrder_____Length.OrderLengthID,
Main.MfgOrder_____Length.LengthType,
Main.MfgOrder_____Length.LocationOnReel,
Main.MfgOrder_____Length.LocationOnLength,
Main.MfgOrder_____Length.TrialNumber,
Main.MfgOrder_____Length.SampleNumber,
Main.MfgOrder_____Length.PrintNumber,
Main.MfgOrder_____Length.Test_Status AS Test_Status_Length,
Main.MfgOrder_____Length.Test_Category,
Main.MfgOrder_____Length.Test_Disposition AS Test_Disposition_Length,
Main.MfgOrder_____Length.SampleSubmittedBy,
Main.MfgOrder_____Length.SampleSubmittedDate,
Main.MfgOrder_____Length.BypassTesting,
Main.MfgOrder_____Length_OperatorQty.Sample1Destination,
Main.MfgOrder_____Length_OperatorQty.Sample2Destination,
Main.MfgOrder_____Length_OperatorQty.Sample3Destination,
Main.MfgOrder______Component.OrderComponentID,
Main.MfgOrder______Component.DesignComponentID,
Main.MfgOrder______Component.ItemNo,
Main.MfgOrder_______Test.LabTestID,
Main.MfgOrder_______Test.OrderTestID,
Main.MfgOrder_______Test.TestComplete,
Main.MfgOrder_______Test.TestStatus,
Main.MfgOrder________Marker2.OrderMarkerID,
Master.Color.ColorName,
Master.LabTest.ExcludeFromPassFail,
CASE
WHEN Main.Design_Component.Component_Label IS NULL
THEN 'Unknown'
ELSE Main.Design_Component.Component_Label
END AS Component_Label
FROM
Main.MfgOrder
INNER JOIN
Main.Design__BOM ON Main.MfgOrder.DesignBOMID = Main.Design__BOM.DesignBOMID
INNER JOIN
Main.Design_Plant ON Main.Design__BOM.DesignPlantID = Main.Design_Plant.DesignPlantID
INNER JOIN
Main.MfgOrder_Operation ON Main.MfgOrder.OrderNumber = Main.MfgOrder_Operation.OrderNumber
INNER JOIN
Main.MfgOrder__Shift ON Main.MfgOrder_Operation.OrderOpID = Main.MfgOrder__Shift.OrderOpID
INNER JOIN
Main.MfgOrder___Event ON Main.MfgOrder__Shift.OrderShiftID = Main.MfgOrder___Event.OrderShiftID
INNER JOIN
Main.MfgOrder____Reel ON Main.MfgOrder___Event.OrderEventID = Main.MfgOrder____Reel.OrderEventID
INNER JOIN
Main.MfgOrder_____Length ON Main.MfgOrder____Reel.OrderReelID = Main.MfgOrder_____Length.OrderReelID
LEFT OUTER JOIN
Main.MfgOrder______Component ON Main.MfgOrder_____Length.OrderLengthID = Main.MfgOrder______Component.OrderLengthID
LEFT OUTER JOIN
Main.MfgOrder_______Test ON Main.MfgOrder______Component.OrderComponentID = Main.MfgOrder_______Test.OrderComponentID
LEFT OUTER JOIN
Main.MfgOrder________Marker2 ON Main.MfgOrder_______Test.OrderTestID = Main.MfgOrder________Marker2.OrderTestID
LEFT OUTER JOIN
Main.Design_Component ON Main.MfgOrder______Component.DesignComponentID = Main.Design_Component.DesignComponentID
LEFT OUTER JOIN
Master.Color ON Main.MfgOrder______Component.TapeColorID = Master.Color.ColorNumber
LEFT OUTER JOIN
Master.LabTest ON Main.MfgOrder_______Test.LabTestID = Master.LabTest.LabTestID
LEFT OUTER JOIN
Main.MfgOrder_____Length_OperatorQty ON Main.MfgOrder______Component.OrderLengthID = Main.MfgOrder_____Length_OperatorQty.OrderLengthID
you can use row_number as below: Below query will not select duplicate only on OrderNumber, if you need to add other columns you add accordingly
Select * from (
Select
RowN = Row_Number() over( partition by Main.MfgOrder.OrderNumber order by Main.MfgOrder.OrderNumber),
--- All your select columns and all your query with joins
) a
Where a.RowN = 1
Is the entire row duplicated exactly? If so then just add DISTINCT
SELECT DISTINCT
...
FROM
...
If you are getting duplicate rows where most columns the same but some columns are different then GROUP BY the columns that are the same and select MIN(column_name) for the ones that are causing the extra rows to appear.

Select distinct rows from multiple column query

I have this query that currently returns all the pertinent information I need, but I need it to only return unique DISPLAYCLAIMNUMBER rows. I have tried throwing a DISTINCT before it, but that gives me an error for invalid syntax. I'm pretty confused on how to put DISTINCT on something that is in the middle of my SELECT. The order of my query is also important, because I'm sending the data to an Excel table. I'm sure this is an extremely inefficient, but the database is very fragmented, and I have to refer to several tables, just for one piece of data. Feel free to improve, if there is a way to.
SELECT cd.NAMECREFID, clm.CONTACTNAME, cd.ASSIGNEDPOLICY, clm.DISPLAYCLAIMNUMBER, clm.CAUSEOFLOSS, scp.PERILCODE, scp.DESCRIBE, clm.ASSIGNEDDATETIME, clm.CLOSEDATETIME, clp.PAYMENT
FROM CLMSTAT clm
inner join SCPERTBL scp on clm.ASSIGNEDPERILNUMBER = scp.PERILCODE
inner join CLMPYMT clp on clm.ASSIGNEDCLAIMNUMBER = clp.ASSIGNEDCLAIMNUMBER
inner join SNAMES sn on clm.CONTACTNAME = sn.NAME
inner join TCUSDTL cd on sn.NAMEID = cd.NAMEID
WHERE clm.CONTACTNAME Like '%Smith%'
ORDER BY clm.CONTACTNAME, clm.ASSIGNEDDATETIME DESC
You should simply try this
SELECT
DISTINCT -- at the start
cd.NAMECREFID, clm.CONTACTNAME, cd.ASSIGNEDPOLICY, clm.DISPLAYCLAIMNUMBER, clm.CAUSEOFLOSS, scp.PERILCODE, scp.DESCRIBE, clm.ASSIGNEDDATETIME, clm.CLOSEDATETIME, clp.PAYMENT
FROM CLMSTAT clm
inner join SCPERTBL scp on clm.ASSIGNEDPERILNUMBER = scp.PERILCODE
inner join CLMPYMT clp on clm.ASSIGNEDCLAIMNUMBER = clp.ASSIGNEDCLAIMNUMBER
inner join SNAMES sn on clm.CONTACTNAME = sn.NAME
inner join TCUSDTL cd on sn.NAMEID = cd.NAMEID
WHERE clm.CONTACTNAME Like '%Smith%'
ORDER BY clm.CONTACTNAME, clm.ASSIGNEDDATETIME DESC
This will give you a unique combination of all columns in the SELECT list.
However if this is not what you desire, and you simply want unique values for clm.DISPLAYCLAIMNUMBER only, I'd ask why do you need rest? If you don't then your query's SELECT list should be like below
SELECT DISTINCT clm.DISPLAYCLAIMNUMBER
FROM CLMSTAT clm
...
SELECT cd.NAMECREFID, clm.CONTACTNAME, cd.ASSIGNEDPOLICY, clm.DISPLAYCLAIMNUMBER, clm.CAUSEOFLOSS, scp.PERILCODE, scp.DESCRIBE, clm.ASSIGNEDDATETIME, clm.CLOSEDATETIME, clp.PAYMENT
FROM CLMSTAT clm
inner join SCPERTBL scp on clm.ASSIGNEDPERILNUMBER = scp.PERILCODE
inner join CLMPYMT clp on clm.ASSIGNEDCLAIMNUMBER = clp.ASSIGNEDCLAIMNUMBER
inner join SNAMES sn on clm.CONTACTNAME = sn.NAME
inner join TCUSDTL cd on sn.NAMEID = cd.NAMEID
WHERE clm.CONTACTNAME Like '%Smith%'
GROUP BY clm.DISPLAYCLAIMNUMBER
ORDER BY clm.CONTACTNAME, clm.ASSIGNEDDATETIME DESC

How to join one select with another when the first one not always returns a value for specific row?

I have a complex query to retrieve some results:
EDITED QUERY (added the UNION ALL):
SELECT t.*
FROM (
SELECT
dbo.Intervencao.INT_Processo, analista,
ETS.ETS_Sigla, ATC.ATC_Sigla, PAT.PAT_Sigla, dbo.Assunto.SNT_Peso,
CASE
WHEN ETS.ETS_Sigla = 'PE' AND (PAT.PAT_Sigla = 'LIB' OR PAT.PAT_Sigla = 'LBR') THEN (0.3*SNT_Peso)
WHEN ETS.ETS_Sigla = 'CD' THEN (0.3*SNT_Peso)*0.3
ELSE SNT_Peso
END AS PESOAREA,
CASE
WHEN a.max_TEA_FimTarefa IS NULL THEN a.max_TEA_InicioTarefa
ELSE a.max_TEA_FimTarefa
END AS DATA_INICIO_TERMINO,
ROW_NUMBER() OVER (PARTITION BY ATC.ATC_Sigla, a.SRV_Id ORDER BY TEA_FimTarefa DESC) AS seqnum
FROM dbo.Tarefa AS t
INNER JOIN (
SELECT
MAX(dbo.TarefaEtapaAreaTecnica.TEA_InicioTarefa) AS max_TEA_InicioTarefa,
MAX (dbo.TarefaEtapaAreaTecnica.TEA_FimTarefa) AS max_TEA_FimTarefa,
dbo.Pessoa.PFJ_Descri AS analista, dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id
FROM dbo.TarefaEtapaAreaTecnica
LEFT JOIN dbo.Tarefa ON dbo.TarefaEtapaAreaTecnica.TRF_Id = dbo.Tarefa.TRF_Id
LEFT JOIN dbo.AreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.AreaTecnica.ATC_Id
LEFT JOIN dbo.ServicoAreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.ServicoAreaTecnica.ATC_Id
AND dbo.Tarefa.SRV_Id = dbo.ServicoAreaTecnica.SRV_Id
INNER JOIN dbo.Pessoa ON dbo.Pessoa.PFJ_Id = dbo.ServicoAreaTecnica.PFJ_Id_Analista
GROUP BY dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id, dbo.Pessoa.PFJ_Descri
) AS a ON t.SRV_Id = a.SRV_Id
INNER JOIN dbo.TarefaEtapaAreaTecnica AS TarefaEtapaAreaTecnica_1 ON
t.TRF_Id = TarefaEtapaAreaTecnica_1.TRF_Id
AND a.ATC_Id = TarefaEtapaAreaTecnica_1.ATC_Id
AND a.max_TEA_InicioTarefa = TarefaEtapaAreaTecnica_1.TEA_InicioTarefa
LEFT JOIN AreaTecnica ATC ON TarefaEtapaAreaTecnica_1.ATC_Id = ATC.ATC_Id
LEFT JOIN Etapa ETS ON TarefaEtapaAreaTecnica_1.ETS_Id = ETS.ETS_Id
LEFT JOIN ParecerTipo PAT ON TarefaEtapaAreaTecnica_1.PAT_Id = PAT.PAT_Id
LEFT OUTER JOIN dbo.Servico ON a.SRV_Id = dbo.Servico.SRV_Id
INNER JOIN dbo.Intervencao ON dbo.Servico.INT_Id = dbo.Intervencao.INT_Id
LEFT JOIN dbo.Assunto ON dbo.Servico.SNT_Id = dbo.Assunto.SNT_Id
) t
The result is following:
It works good, the problem is that I was asked that if when a row is not present on this query, it must contain values from another table (ServicoAreaTecnica), so I got this query for the other table based on crucial information of the first query. So if I UNION ALL I get this:
Query1 +
UNION ALL
SELECT INN.INT_Processo,
PES.PFJ_Descri,
NULL, --ETS.ETS_Sigla,
ART.ATC_Sigla,
NULL ,--PAT.PAT_Sigla,
ASS.SNT_Peso,
NULL, --PESOAREA
NULL, --DATA_INICIO_TERMINO
NULL --seqnum
FROM dbo.ServicoAreaTecnica AS SAT
INNER JOIN dbo.AreaTecnica AS ART ON ART.ATC_Id = SAT.ATC_Id
INNER JOIN dbo.Servico AS SER ON SER.SRV_Id = SAT.SRV_Id
INNER JOIN dbo.Assunto AS ASS ON ASS.SNT_Id = SER.SNT_Id
INNER JOIN dbo.Intervencao AS INN ON INN.INT_Id = SER.INT_Id
INNER JOIN dbo.Pessoa AS PES ON PES.PFJ_Id = SAT.PFJ_Id_Analista
The result is following:
So what I want to do is to remove row number 1 because row number 2 exists on the first query, I think I got it explained better this time. The result should be only row number 1, row number 2 would appear only if query 1 doesn't retrieve a row for that particular INN.INT_Processo.
Thanks!
Ok, there are two ways to reduce your record set. Given that you've already written the code to produce the table with the extra rows, it might be easiest to just add code to reduce that:
Select * from
(Select *
, Row_Number() over
(partition by IntProcesso, Analista order by ISNULL(seqnum, 0) desc) as RN
from MyResults) a
where RN = 1
This will assign row_number 1 to any rows that came from your first query, or to any rows from the second query that do not have matches in the first query, then filter out extra rows.
You could also use outer joins with isnull or coalesce, as others have suggested. Something like this:
Select ISNULL(a.IntProcesso, b.IntProcesso) as IntProcesso
, ISNULL(a.Analista, b.Analista) as Analista
, ISNULL(a.ETSsigla, b.ETSsigla) as ETSsigla
[repeat for the rest of your columns]
from Table1 a
full outer join Table2 b
on a.IntProcesso = b.IntProcesso and a.Analista = b.Analista
Your code is hard to read, because of the lengthy names of everything (and to be honest, the fact that they're in a language I don't speak also makes it a lot harder).
But how about: replacing your INNER JOINs with LEFT JOINs, adding more LEFT JOINs to draw in the alternative tables, and introducing ISNULL clauses for each variable you want in the results?
If you do something like ... Query1 Right Join Query2 On ... that should get only the rows in Query2 that don't appear in Query 1.

TSQL Inner select using outer join

I have a query that is working for the most part until I had to add the inner select for "Trainers".
As you can see in the code below, I am trying to get all of the trainers for each of the segment ID's.
I am getting an error on the first inner selects where clause WHERE trn.segmentID = tes.teSegmentID saying that tes.teSegmentID is not defined.
Is there another way to approach this query in order to get the trainers like I am trying to accomplish?
SELECT *,
(SELECT e2.[FirstName] AS trainerFirst,
e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN
employeeTable AS e2
ON trn.trainerEmpID = e2.EmpID
WHERE trn.segmentID = tes.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers'))
FROM dbo.BS_TrainingEvents AS a
WHERE a.trainingEventID IN (SELECT tes.trainingEventID
FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN
dbo.BS_TrainingEvent_SegmentDetails AS tesd
ON tesd.segmentID = tes.teSegmentID
INNER JOIN
dbo.BS_LocaleCodes AS locale
ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore');
It seems like you're taking the scenic route towards this:
SELECT a.*,
X.[FirstName],
X.[LastName]
FROM dbo.BS_TrainingEvents AS a
LEFT OUTER JOIN (SELECT e2.[FirstName], e2.[LastName], locale.location FROM dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_Training_Trainers AS trn ON trn.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID) AS X ON a.trainingEventID = X.trainingEventID
WHERE X.location = 'Baltimore';
Not sure if I got all those joins right, it was hard to decode from all the nesting you have going on.
If I have guessed table relationships from their names correctly, the only way to solve this is to reference the same filtering condition twice: first, in the XML generation part, and second in the outer level of the query:
with cte as (
select distinct tes.trainingEventID, tes.teSegmentID
from dbo.BS_TrainingEvent_Segments AS tes
INNER JOIN dbo.BS_TrainingEvent_SegmentDetails AS tesd ON tesd.segmentID = tes.teSegmentID
INNER JOIN dbo.BS_LocaleCodes AS locale ON locale.localeID = tesd.localeID
WHERE locale.location = 'Baltimore'
)
SELECT a.*, (
SELECT e2.[FirstName] AS trainerFirst, e2.[LastName] AS trainerLast
FROM BS_Training_Trainers AS trn
LEFT OUTER JOIN employeeTable AS e2 ON trn.trainerEmpID = e2.EmpID
inner join cte c on trn.segmentID = c.teSegmentID
FOR XML PATH ('trainer'), TYPE, ELEMENTS, ROOT ('trainers')
)
FROM dbo.BS_TrainingEvents AS a
where exists (select 0 from cte c where c.testrainingEventID = a.trainingEventID);
It's difficult to tell whether this is completely correct, of course, but I hope you get the idea.
Oh yes, and if you would have an event with multiple Baltimore segments, you will never be able to tell which trainer takes which one. But you can always add more data into XML to resolve this.

How to join additional table when left outer not working

I have an existing proc which I have chopped up for brevity's sake
SELECT col1, col2
FROM (
col1, col2
SELECT col3--aggregate columns
FROM iep i
INNER JOIN student s ON s.studentID = i.studentID
INNER JOIN dbo.IDuration id ON i.IepID = id.iepID
INNER JOIN AppointmentStudent as ON s.studentID = as.studentID
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
WHERE s.studentID = #studentID
GROUP BY col1, col2
) t
The aggregate columns summarizes appointments into the weeks of the year, but it only does sos for the weeks the student had appointments. I have an additional table called SchoolWeekYear that is populated with all of the weeks of the year that I am trying to integrate to this proc so I get 52 records back and not just the handful I am currently getting.
SELECT col1, col2
FROM (
col1, col2
SELECT col3--aggregate columns
FROM iep i
INNER JOIN student s ON s.studentID = i.studentID
INNER JOIN dbo.IDuration id ON i.IepID = id.iepID
INNER JOIN AppointmentStudent as ON s.studentID = as.studentID
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
LEFT OUTER JOIN SchoolWeekYear swy on a.calWeekNumber = swy.calWeekNumber
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
WHERE s.studentID = #studentID
GROUP BY col1, col2
) t
Is this possible?
You need to integrate SchoolWeekYear into the existing table set at an earlier stage.
To show you the principle, let us simplify the problem even further. Let there be a table called WeeklyData with columns WeekNumber and SomeData. Some weeks might have multiple entries, some others none. So this query
SELECT
WeekNumber,
AGG(SomeData)
FROM
WeeklyData
GROUP BY
WeekNumber
;
would return only weeks present in WeeklyData. If you want to return data for all weeks, use a corresponding reference table (let it be called AllWeeks) like this:
SELECT
aw.WeekNumber,
AGG(wd.SomeData)
FROM
AllWeeks AS aw
LEFT JOIN
WeeklyData AS wd ON aw.WeekNumber = wd.WeekNumber
GROUP BY
aw.WeekNumber
;
So, you take the reference table (AllWeeks) and join the data table (WeeklyData) to it, not the other round.
Now, what if the original query was slightly more complex? Let us now suppose the data table is called StudentWeeklyData and has a column called StudentID which is a reference to a Students table. Let us also imagine the query is similar to yours in that it logically includes the Students table before the data table is joined and filters the results on the primary key of Students:
SELECT
s.StudentID,
s.StudentName,
swd.WeekNumber,
AGG(swd.SomeData)
FROM
Students AS s
INNER JOIN
StudentWeeklyData AS swd ON s.StudentID = swd.StudentID
WHERE
s.StudentID = #StudentID
GROUP BY
s.StudentID,
s.StudentName,
swd.WeekNumber
;
(Not every detail matters here, I just wanted to use a more similar example for you that would still be simple enough to understand.) Again, this would return only weeks where the specified student has data in StudentWeeklyTable. If you wanted to return all weeks for the student (some of them potentially empty, of course), this is how you could go about it:
SELECT
s.StudentID,
s.StudentName,
aw.WeekNumber,
AGG(swd.SomeData)
FROM
Students AS s
CROSS JOIN
AllWeeks AS aw
LEFT JOIN
StudentWeeklyData AS swd ON s.StudentID = swd.StudentID
AND aw.WeekNumber = swd.WeekNumber
WHERE
s.StudentID = #StudentID
GROUP BY
s.StudentID,
s.StudentName,
aw.WeekNumber
;
Here you can see again that the AllWeeks table is included before the data table. The difference to the previous case is we are not left-joining the result of the join between Students and StudentWeekly to AllWeeks, nor are we left-joining the data table itself specifically to AllWeeks. Instead, the data table is joined to the result of a cross join, Students × AllWeeks.
Returning to your specific situation, I realise that in your case even more tables are involved. Since you are not specifying how all those tables are related to one another, I can only guess that SchoolWeekYear should be cross-joined somewhere after FROM and before this line:
INNER JOIN Appointment a ON as.appointmentID = a.appointmentID
and that the said line should be modified like this:
LEFT JOIN Appointment a ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
the swy being an alias assigned to SchoolWeekYear.
It is also worth noting that there is a subsequent inner join with AppointmentTherapist. That join would eliminate the effect of the above left join if it remained unchanged, because its condition references the Appointment table. Perhaps, the syntactically easiest way to fix the issue would be to change that inner join to a left one too, although there is another way: instead of
LEFT JOIN Appointment a ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
LEFT JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
you could use this syntax:
LEFT JOIN
Appointment a
INNER JOIN AppointmentTherapist at ON a.appointmentID = at.appointmentID
ON as.appointmentID = a.appointmentID
AND swy.calWeekNumber = a.calWeekNumber
That way the logical order of joining would be changed: Appointment and AppointmentTherapist would be first inner-joined with each other, then the result set would be outer-joined to the result of the previously specified joins.
It is possible. But if you have multiple row with some calWeekNumber on the SchoolWeekYear table, your aggregate function return wrong result.
If you want all lines in SchoolWeekYear shown, regardless of a match, you should use RIGHT OUTER JOIN instead of LEFT.

Resources