SQL multiple left join in subquery? - sql

Any idea on how to resolve this query dependency issue? Would subquery help? Database I'm using is sql server 2012.
FROM [Scheduling].[studentsection] AS [table027]
Left JOIN [Grading].[StudentGradeBucket] AS [table028]
ON ([table028].[StudentSectionID] = [table027].[StudentSectionID])
And (#0 = [table002].[label])
Left JOIN [Grading].[GradingPeriodGradeBucket] AS [table029]
ON [table028].[GradingPeriodGradeBucketID] = [table029].[GradingPeriodGradeBucketID]
Left JOIN [Grading].[GradeBucket] AS [table002]
ON [table029].[GradeBucketID] = [table002].[GradeBucketID]
Left JOIN [Grading].[GradeBucketType] AS [table001]
ON [table002].[GradeBucketTypeID] = [table001].[GradeBucketTypeID]
Left JOIN [Grading].[GradeMark] AS [table022]
ON [table028].[GradeMarkID] = [table022].[GradeMarkID]
The dependency issue I have is with this:
#0 = [table002].[label] //#0 is a string variable
Like the join hasn't been created yet but I need to use it to create the join for relationship [Grading].[StudentGradeBucket] or [table028]

That is weird circular join logic you are using and these table alias's you have chosen are making it more confusing. Alias's should simplify, not confuse. That said, I think it can just be moved to the where clause:
...
Left JOIN [Grading].[GradeMark] AS [table022] ON [table028].[GradeMarkID] = [table022].[GradeMarkID]
where #0 = [table002].[label]
If that fails, you may need to redefine your logic...it seems a bit circular to me.

Try this:
declare #0 nvarchar(max) = 'label value'
select *
from [Scheduling].[studentsection] as ss
left join [Grading].[StudentGradeBucket] as sgb
on sgb.[StudentSectionID] = ss.[StudentSectionID]
inner join [Grading].[GradingPeriodGradeBucket] as gpgb
on gpgb.[GradingPeriodGradeBucketID] = sgb.[GradingPeriodGradeBucketID]
inner join [Grading].[GradeBucket] as gb
on gb.[GradeBucketID] = gpgb.[GradeBucketID]
and gb.[label] = #0
left join [Grading].[GradeBucketType] as gbt
on gbt.[GradeBucketTypeID] = gb.[GradeBucketTypeID]
left join [Grading].[GradeMark] as gm
on gm.[GradeMarkID] = sgb.[GradeMarkID]
Or this if you really want left outer joins:
declare #0 nvarchar(max) = 'label value'
select *
from [Scheduling].[studentsection] as ss
left join [Grading].[StudentGradeBucket] as sgb
on sgb.[StudentSectionID] = ss.[StudentSectionID]
left join [Grading].[GradingPeriodGradeBucket] as gpgb
on gpgb.[GradingPeriodGradeBucketID] = sgb.[GradingPeriodGradeBucketID]
left join [Grading].[GradeBucket] as gb
on gb.[GradeBucketID] = gpgb.[GradeBucketID]
and gb.[label] = #0
left join [Grading].[GradeBucketType] as gbt
on gbt.[GradeBucketTypeID] = gb.[GradeBucketTypeID]
left join [Grading].[GradeMark] as gm
on gm.[GradeMarkID] = sgb.[GradeMarkID]
Or if you need the logic of only returning results from the StudentGradeBucket when there's a matching GradeBucket record; this:
declare #0 nvarchar(max) = 'label value'
select *
from [Scheduling].[studentsection] as ss
left join [Grading].[StudentGradeBucket] as sgb
on sgb.[StudentSectionID] = ss.[StudentSectionID]
left join [Grading].[GradingPeriodGradeBucket] as gpgb
on gpgb.[GradingPeriodGradeBucketID] = sgb.[GradingPeriodGradeBucketID]
left join [Grading].[GradeBucket] as gb
on gb.[GradeBucketID] = gpgb.[GradeBucketID]
left join [Grading].[GradeBucketType] as gbt
on gbt.[GradeBucketTypeID] = gb.[GradeBucketTypeID]
left join [Grading].[GradeMark] as gm
on gm.[GradeMarkID] = sgb.[GradeMarkID]
where
( --filter on the gb label only if there's a result from the sgb table;
sgb.[StudentSectionID] is null
or and gb.[label] = #0
)

Related

How can I transform this Code with Joins instead of using +(=) or =

I was trying Hours to transform this code(I think It is Oracle) with joins in SQL Server instead of
using +(=)/= but somehow i dont get the same result as using += or =. Can please someone help me out ?
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1, KNVV, KNVP, CDHDR
WHERE
AND `(KNVV.MANDT = KNA1.MANDT`
AND `KNVV.KUNNR = KNA1.KUNNR)`
AND `(KNVP.MANDT (+) = KNVV.MANDT`
AND `KNVP.KUNNR (+) = KNVV.KUNNR`
AND `KNVP.VTWEG (+) = KNVV.VTWEG)`
AND `(CDHDR.MANDANT (+) = KNVV.MANDT`
AND `CDHDR.OBJECTID (+) = KNVV.KUNNR)`
AND `(KNVV.VTWEG = KNVP.VTWEG)`
AND `KNVP.PARVW (+) = 'RG'`
AND CDHDR.OBJECTCLAS (+) = 'DEBI'
Without sample data its hard to test but it appears you want:
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1
INNER JOIN KNVV
ON ( KNVV.MANDT = KNA1.MANDT
AND KNVV.KUNNR = KNA1.KUNNR
)
INNER JOIN KNVP
ON ( KNVP.MANDT = KNVV.MANDT
AND KNVP.KUNNR = KNVV.KUNNR
AND KNVP.VTWEG = KNVV.VTWEG
AND KNVV.VTWEG = KNVP.VTWEG -- This duplicated condition makes it an
-- INNER JOIN and not a LEFT OUTER JOIN as
-- you are not using (+) in Oracle's legacy
-- syntax.
AND KNVP.PARVW = 'RG'
)
LEFT OUTER JOIN CDHDR
ON ( CDHDR.MANDANT = KNVV.MANDT
AND CDHDR.OBJECTID = KNVV.KUNNR
AND CDHDR.OBJECTCLAS = 'DEBI'
)
What you probably want is to make the second join a LEFT OUTER JOIN instead of an INNER JOIN but that is not what your current query is doing as you are using (KNVV.VTWEG = KNVP.VTWEG) rather than (KNVV.VTWEG = (+) KNVP.VTWEG) in your Oracle query.
You query can be converted to:
select
KNVV.MANDT,
KNVV.KUNNR,
KNVV.VTWEG,
KNVV.BZIRK,
KNVP.KUNN2
from KNA1
join KNVV on KNVV.MANDT = KNA1.MANDT
and KNVV.KUNNR = KNA1.KUNNR
left join KNVP on KNVP.MANDT = KNVV.MANDT -- left join defeated!
and KNVP.KUNNR = KNVV.KUNNR
and KNVP.VTWEG = KNVV.VTWEG
and KNVP.PARVW = 'RG'
left join CDHDR on CDHDR.MANDANT = KNVV.MANDT
and CDHDR.OBJECTID = KNVV.KUNNR
and CDHDR.OBJECTCLAS = 'DEBI'
where KNVV.VTWEG = KNVP.VTWEG -- silently converts left join into inner join
NOTE: the original query is malformed
Even though the original query tried to perform a left join against the table KNVP this join is silently converted into an inner join by the engine. Are you sure this query is working as expected?
Did you try inner JOIN?
SELECT KNVV.MANDT, KNVV.KUNNR,
KNVV.VTWEG, KNVV.BZIRK, KNVP.KUNN2
FROM KNA1, KNVV, KNVP, CDHDR
INNER JOIN KNVV ON KNA1.MANDT=KNVV.MANDT;
Something in this sense its more convenient.
documentation bellow
https://www.w3schools.com/sql/sql_join.asp

SQL Selects combine - Second select to be in Where clause

I have 2 selects. The first one:
select purs.t_orno as purchased
from ttisfc001201 sls
inner join twhinr110201 sfc on sfc.t_orno = sls.t_pdno
inner join twhltc100201 purs on purs.t_clot=sfc.t_clot
left join twhltc220201 items on items.t_clot = sfc.t_clot
left join twhltc210201 cert_num on cert_num.t_item = items.t_item
left join twhltc200201 cert on cert.t_ltft = cert_num.t_ltft
where sls.t_cprj = 'SLS004336' and purs.t_orno like N'PUR%'
and sfc.t_koor = 1 and sfc.t_kost = 5
Is giving me these results:
PUR007833
PUR008544
PUR008698
PUR008963
PUR009048
PUR009304
PUR009611
PUR009912
PUR009913
PUR010006
PUR010110
PUR010400
PUR010465
PUR010539
PUR010664
So basically these are results I must use in the second select in where clause. A field from table in second select must be equal to one of them. To understand me better it should look like this:
select distinct fac.t_isup
from ttfacp200201 fac
inner join ttfacp250201 mid on mid.t_ityp = fac.t_ttyp and mid.t_idoc=fac.t_ninv
where mid.t_orno ='PUR010400' or mid.t_orno='PUR009912'or mid.t_orno='PUR009913'or mid.t_orno='PUR010465'or mid.t_orno='PUR008544'or mid.t_orno='PUR008963'or mid.t_orno='PUR009048'or mid.t_orno='PUR010110'or mid.t_orno='PUR007833'or mid.t_orno='PUR009304'or mid.t_orno='PUR009611'or mid.t_orno='PUR010664'or mid.t_orno='PUR010006'or mid.t_orno='PUR010539'or mid.t_orno='PUR008698'or mid.t_orno='PUR010667'
All these ORs are results from the first select. How I can combine them (the first select to go in second select where clause) so I can get results at once?
You can use the IN clause for your second query
select distinct fac.t_isup
from ttfacp200201 fac
inner join ttfacp250201 mid on mid.t_ityp = fac.t_ttyp and mid.t_idoc=fac.t_ninv
where mid.t_orno IN (
select purs.t_orno
from ttisfc001201 sls
inner join twhinr110201 sfc on sfc.t_orno = sls.t_pdno
inner join twhltc100201 purs on purs.t_clot=sfc.t_clot
left join twhltc220201 items on items.t_clot = sfc.t_clot
left join twhltc210201 cert_num on cert_num.t_item = items.t_item
left join twhltc200201 cert on cert.t_ltft = cert_num.t_ltft
where sls.t_cprj = 'SLS004336' and purs.t_orno like N'PUR%'
and sfc.t_koor = 1 and sfc.t_kost = 5
)
Something like this
;with first_query_cte(purchased) as (
select purs.t_orno
from ttisfc001201 sls
inner join twhinr110201 sfc on sfc.t_orno = sls.t_pdno
inner join twhltc100201 purs on purs.t_clot=sfc.t_clot
left join twhltc220201 items on items.t_clot = sfc.t_clot
left join twhltc210201 cert_num on cert_num.t_item = items.t_item
left join twhltc200201 cert on cert.t_ltft = cert_num.t_ltft
where sls.t_cprj = 'SLS004336' and purs.t_orno like N'PUR%'
and sfc.t_koor = 1 and sfc.t_kost = 5)
select distinct fac.t_isup
from ttfacp200201 fac
inner join ttfacp250201 mid on mid.t_ityp = fac.t_ttyp and mid.t_idoc=fac.t_ninv
inner join first_query_cte fqc on mid.t_orno=fqc.purchased;

incorrect syntax near the keyword where for using subquery

SELECT DISTINCT dbo.master_order.order_no,
dbo.master_order.program_no,
dbo.Setup_size.size_name,
dbo.Setup_color.color_name,
dbo.Setup_color.color_no,
dbo.transaction_production.total_weight,
dbo.Setup_yarn.yarn_count,
dbo.Setup_article_order.article_name,
dbo.master_order.shipment_date,
#from AS reprt,
#to AS reprt1,
dbo.transaction_order.quantity,
dbo.transaction_order.gsm
FROM dbo.master_order
INNER JOIN dbo.transaction_order ON dbo.master_order.order_id = dbo.transaction_order.order_id
INNER JOIN dbo.transaction_production ON dbo.transaction_order.trans_id = dbo.transaction_production.trans_id
INNER JOIN dbo.Setup_size ON dbo.transaction_order.size_id = dbo.Setup_size.size_id
INNER JOIN dbo.Setup_yarn ON dbo.transaction_order.yarn_id = dbo.Setup_yarn.yarn_id
INNER JOIN dbo.Setup_article_order ON dbo.transaction_order.article_id = dbo.Setup_article_order.article_id
INNER JOIN dbo.Setup_color ON dbo.transaction_order.color_id = dbo.Setup_color.color_id
AND dbo.Setup_yarn.color_id = dbo.Setup_color.color_id
WHERE dbo.setup_color.color_id=
(SELECT color_no
FROM dbo.setup_color) WHERE master_order.shipment_date>=#from
AND master_order.shipment_date<=#to
This is your syntax after WHERE clause
where dbo.setup_color.color_id=
(select color_no from dbo.setup_color)
where master_order.shipment_date>=
#from and master_order.shipment_date<=#to
there are 2 Where clauses used on main Query.
use in instead of equals for a subquery.
SELECT DISTINCT
dbo.master_order.order_no,
dbo.master_order.program_no,
dbo.Setup_size.size_name,
dbo.Setup_color.color_name,
dbo.Setup_color.color_no,
dbo.transaction_production.total_weight,
dbo.Setup_yarn.yarn_count,
dbo.Setup_article_order.article_name,
dbo.master_order.shipment_date,
#from as reprt,
#to as reprt1,
dbo.transaction_order.quantity,
dbo.transaction_order.gsm
FROM dbo.master_order
INNER JOIN dbo.transaction_order ON dbo.master_order.order_id = dbo.transaction_order.order_id
INNER JOIN dbo.transaction_production ON dbo.transaction_order.trans_id = dbo.transaction_production.trans_id
INNER JOIN dbo.Setup_size ON dbo.transaction_order.size_id = dbo.Setup_size.size_id
INNER JOIN dbo.Setup_yarn ON dbo.transaction_order.yarn_id = dbo.Setup_yarn.yarn_id
INNER JOIN dbo.Setup_article_order ON dbo.transaction_order.article_id = dbo.Setup_article_order.article_id
INNER JOIN dbo.Setup_color ON dbo.transaction_order.color_id = dbo.Setup_color.color_id
AND dbo.Setup_yarn.color_id = dbo.Setup_color.color_id where dbo.setup_color.color_id in
(select color_no from dbo.setup_color) where master_order.shipment_date >= #from and master_order.shipment_date<= #to
The problem is that you have 2 WHERE clauses in the main query. as master_order is a table used in main query, just replace 2nd WHERE withAND as below.
SELECT DISTINCT dbo.master_order.order_no,
dbo.master_order.program_no,
dbo.Setup_size.size_name,
dbo.Setup_color.color_name,
dbo.Setup_color.color_no,
dbo.transaction_production.total_weight,
dbo.Setup_yarn.yarn_count,
dbo.Setup_article_order.article_name,
dbo.master_order.shipment_date,
#from AS reprt,
#to AS reprt1,
dbo.transaction_order.quantity,
dbo.transaction_order.gsm
FROM dbo.master_order
INNER JOIN dbo.transaction_order ON dbo.master_order.order_id = dbo.transaction_order.order_id
INNER JOIN dbo.transaction_production ON dbo.transaction_order.trans_id = dbo.transaction_production.trans_id
INNER JOIN dbo.Setup_size ON dbo.transaction_order.size_id = dbo.Setup_size.size_id
INNER JOIN dbo.Setup_yarn ON dbo.transaction_order.yarn_id = dbo.Setup_yarn.yarn_id
INNER JOIN dbo.Setup_article_order ON dbo.transaction_order.article_id = dbo.Setup_article_order.article_id
INNER JOIN dbo.Setup_color ON dbo.transaction_order.color_id = dbo.Setup_color.color_id
AND dbo.Setup_yarn.color_id = dbo.Setup_color.color_id
WHERE dbo.setup_color.color_id=
(SELECT color_no
FROM dbo.setup_color)
AND master_order.shipment_date>=#from
AND master_order.shipment_date<=#to
Also if the table dbo.setup_color has more than 1 value, either use IN instead of = or add a WHERE clause to the inner query to return just one value, otherwise it will throw error.

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

SQL with left outer join and 3 tables

I would like to add an ADD at the end of my code. Please have a look on my code and thanks for your support:
SELECT Area.org,
Supervisors.NomSup,
Supervisors.PrenomSup,
Employees.NomEmp,
Employees.PrenomEmp,
Employees.NoIdAlcanEmp,
Competencies.CodeCompetencies,
Competencies.CompetencyName,
LinkResultComp.AssNote,
LinkResultComp.AssDate
FROM ((((((
Area INNER JOIN Supervisors ON Area.IdArea = Supervisors.IdArea
)
INNER JOIN Employees ON Supervisors.IdSupervisor = Employees.IdSupervisor
)
INNER JOIN LinkProfilesEmployees ON Employees.IdEmp = LinkProfilesEmployees.IdEmp
)
INNER JOIN Profiles ON Profiles.IdProfiles = LinkProfilesEmployees.IdProfiles
)
INNER JOIN LinkProfComp ON Profiles.IdProfiles = LinkProfComp.IdProfiles
)
INNER JOIN Competencies ON Competencies.IdCompetencies = LinkProfComp.IdCompetencies
)
LEFT OUTER JOIN LinkResultComp ON (Competencies.IdCompetencies = LinkResultComp.IdCompetencies AND ON Competencies.IdCompetencies = LinkResultComp.IdCompetencies)
WHERE Area.org LIKE "*20*" AND Competencies.CodeCompetencies LIKE "khse2010-05"
ORDER BY Supervisors.NomSup, Employees.NomEmp;
Just remove the extra ON that you added
So change this
LEFT OUTER JOIN LinkResultComp
ON (Competencies.IdCompetencies = LinkResultComp.IdCompetencies
AND ON Competencies.IdCompetencies = LinkResultComp.IdCompetencies)
------^^ This one
to this
LEFT OUTER JOIN LinkResultComp
ON (Competencies.IdCompetencies = LinkResultComp.IdCompetencies
AND Competencies.IdCompetencies = LinkResultComp.IdCompetencies)
Of course I assume you meant different fields for the second condition