Why can't I connect OUTER JOIN tables? - sql

I have a table of teachers and each teacher can also be a principal.
I have to introduce a certain teacher and all his principals.
He does it well for me in this code:
WITH teacherTablecte AS
(SELECT teacher.IdTeacher, teacher.FirstName, teacher.LastName,
teacher.PhoneNumber,teacher.ManagerId, 1 as 'EmpLevel', boss.[FirstName]+'
'+boss.LastName as bossName
FROM [dbo].[T_Teachers] teacher JOIN [dbo].[T_Teachers] boss
ON teacher.ManagerId = boss.IdTeacher
WHERE teacher.IdTeacher =2011
UNION ALL
SELECT teacher.IdTeacher, teacher.FirstName, teacher.LastName,
teacher.PhoneNumber,teacher.ManagerId, teacherTablecte.EmpLevel + 1, boss.
[FirstName]+' '+boss.LastName
FROM [dbo].[T_Teachers] teacher
JOIN teacherTablecte
ON teacher.IdTeacher = teacherTablecte.ManagerId JOIN [dbo].[T_Teachers]
boss on
teacher.MANAGERID= boss.IdTeacher
)
SELECT *
FROM teacherTablecte
But he does not introduce me to the Chief Executive
I tried to convert
WITH teacherTablecte AS
(SELECT teacher.IdTeacher, teacher.FirstName, teacher.LastName,
teacher.PhoneNumber,teacher.ManagerId, 1 as 'EmpLevel', boss.[FirstName]+'
'+boss.LastName as
bossName
FROM [dbo].[T_Teachers] teacher JOIN [dbo].[T_Teachers] boss
ON teacher.ManagerId = boss.IdTeacher
WHERE teacher.IdTeacher =2011
UNION ALL
SELECT teacher.IdTeacher, teacher.FirstName, teacher.LastName,
teacher.PhoneNumber,teacher.ManagerId, teacherTablecte.EmpLevel + 1, boss.
[FirstName]+'
'+boss.LastName
FROM [dbo].[T_Teachers] teacher
JOIN teacherTablecte
ON teacher.IdTeacher = teacherTablecte.ManagerId OUTER JOIN [dbo].
[T_Teachers] boss on
teacher.MANAGERID= boss.IdTeacher
)
SELECT *
FROM teacherTablecte
but the JOIN to OUTER JOIN but I get this error: Msg 462, Level 16, State 1, Line 2
Outer join is not allowed in the recursive part of a recursive common table expression 'teacherTablecte'.

Related

Combine SQL statements as columns, not as rows

First Query:
SELECT OPENING.COMP_CODE, COMPANY.COMP_NAME, OPENING.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM OPENING
LEFT JOIN COMPANY ON OPENING.COMP_CODE = COMPANY.COMP_CODE
LEFT JOIN QUALIFICATION ON OPENING.QUAL_CODE = QUALIFICATION.QUAL_CODE
Second Query:
SELECT EDUCATION.CAND_NUM, CANDIDATE.CAND_LNAME, EDUCATION.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM EDUCATION
LEFT JOIN CANDIDATE ON EDUCATION.CAND_NUM = CANDIDATE.CAND_NUM
LEFT JOIN QUALIFICATION ON EDUCATION.QUAL_CODE = QUALIFICATION.QUAL_CODE
I tried using <Query1> UNION ALL <Query2> but it combines the results as rows. I want to combine the results as columns (side by side)
If you need to bring all the result in one row, UNION ALL / UNION wont work. Use cross apply instead. Such as,
SELECT A.* ,B.*
FROM
(
SELECT
OPENING.COMP_CODE, COMPANY.COMP_NAME, OPENING.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM OPENING
LEFT JOIN COMPANY ON OPENING.COMP_CODE = COMPANY.COMP_CODE
LEFT JOIN QUALIFICATION ON OPENING.QUAL_CODE = QUALIFICATION.QUAL_CODE
) AS A
CROSS APPLY
(
SELECT EDUCATION.CAND_NUM, CANDIDATE.CAND_LNAME, EDUCATION.QUAL_CODE, QUALIFICATION.QUAL_DESCRIPTION
FROM EDUCATION
LEFT JOIN CANDIDATE ON EDUCATION.CAND_NUM = CANDIDATE.CAND_NUM
LEFT JOIN QUALIFICATION ON EDUCATION.QUAL_CODE = QUALIFICATION.QUAL_CODE
) AS B

Return the ID's & first and last names of all students who have taken both ENG 101 and ENG 102 (2 columns, 11 rows)

I've created two instances of the tables using aliases But my query doesn't return any results when I search for student who has taken one AND the other class.
select s01.StudentID, s01.StudFirstName, s01.StudLastName
from Students s01
join Student_Schedules as ss01
on s01.StudentID = ss01.StudentID
join Classes as c01
on ss01.ClassID = c01.ClassID
join Subjects as sbj01
on c01.SubjectID = sbj01.SubjectID
--rejoins
join Students as s02
on s01.StudentID = s02.StudentID
join Student_Schedules as ss02
on ss01.StudentID = ss02.StudentID
join Classes as c02
on c01.ClassID = c02.ClassID
join Subjects as sbj02
on sbj01.SubjectID = sbj02.SubjectID
where sbj01.SubjectCode like 'ENG 101'
and sbj02.SubjectCode like 'ENG 102';
If you wanted all the students who have taken 3 subjects or more would you use triple joins (or more)?
This is a performance killer.
Instead of all these double joins, join once, filter and aggregate with a condition in the having clause:
select s.StudentID, s.StudFirstName, s.StudLastName
from Students s
join Student_Schedules as ss on s.StudentID = ss.StudentID
join Classes as c on ss.ClassID = c.ClassID
join Subjects as sbj on c.SubjectID = sbj.SubjectID
where sbj.SubjectCode in ('ENG 101', 'ENG 102')
group by s.StudentID, s.StudFirstName, s.StudLastName
having count(distinct sbj.SubjectCode) = 2
I believe that distinct is not really needed in count() if there are no duplicates.
I think that this is what you mean:
select s.StudentID, s.StudFirstName, s.StudLastName
from Students s
join Student_Schedules as ss01 on s.StudentID = ss01.StudentID
join Classes as c01 on ss01.ClassID = c01.ClassID
join Subjects as sbj01 on c01.SubjectID = sbj01.SubjectID
join Student_Schedules as ss02 on s.StudentID = ss02.StudentID
join Classes as c02 on ss02.ClassID = c02.ClassID
join Subjects as sbj02 on c02.SubjectID = sbj02.SubjectID
where sbj01.SubjectCode = 'ENG 101' and sbj02.SubjectCode = 'ENG 102';
Explanation:
your query is trying to find a student who took both 'ENG 101' and 'ENG 102' classes; for this, you are following two different paths (Students > Student_Schedule > Subjects)
but you are using join conditions such as ss01.StudentID = ss02.StudentID, which force both paths to be identical; so you actually end up looking for a Subject whose code is both 'ENG 101' and 'ENG 102', which is not possible
I fixed the join conditions to what I think that you want.
Side notes:
you don't need to bring in Students twice
LIKE 'ENG 101' is equivalent to = 'ENG 101'
Personally I would re-arrange the logic using exists as this is how I would be thinking about it in my mind.
I would use the full join name, inner join for clarity.
I would fully qualify the table names with the schema name e.g. dbo.
I would use = instead of like as you are not performing a wildcard search
select s01.StudentID, s01.StudFirstName, s01.StudLastName
from dbo.Students s01
where exists (
select 1
from dbo.Student_Schedules as ss01
inner join dbo.Classes as c01 on ss01.ClassID = c01.ClassID
inner join dbo.Subjects as sbj01 on c01.SubjectID = sbj01.SubjectID
where s01.StudendID = ss01.StudendID
and sbj01.SubjectCode = 'ENG 101'
)
and exists (
select 1
from dbo.Student_Schedules as ss02
inner join dbo.Classes as c02 on ss02.ClassID = c02.ClassID
inner join dbo.Subjects as sbj02 on c02.SubjectID = sbj02.SubjectID
where s01.StudendID = ss02.StudendID
and sbj02.SubjectCode = 'ENG 102'
)

Syntax error in sql Query Design

I have design one query such as
Select Temp3.*
From (
(Select temp1.alletec_ce1name,temp1.employeeid, count (temp1.alletec_mifid) AS MifAssign,alletec_mifid
from (select MIF.alletec_ce1name,User1.employeeid,MIF.alletec_mifid from Filteredalletec_mif as MIF FULL OUTER JOIN FilteredSystemUser As User1 on MIF.alletec_ce1=User1.systemuserid
FULL OUTER JOIN FilteredBusinessUnit as BU ON User1.businessunitid=BU.businessunitid
where MIF.alletec_organisationname='Konica Minolta India' AND MIF.alletec_cityname ='Delhi' AND
MIF.alletec_regionname ='North' ) as temp1
Group by temp1.alletec_mifid,temp1.alletec_ce1name,temp1.employeeid ) as Temp2 Inner Join FilteredIncident As Incident On Incident.alletec_serialnomif=Temp2.alletec_mifid ) as temp3
Now the issue is it is showing the Syntax error near the first from. What can be the possible reason for that. Thanks in advance.
I have one more query, such as
with temp2 (
alletec_ce1name,
employeeid,
alletec_mifid,
alletec_cityname,
alletec_regionname
)
as(
Select temp1.alletec_ce1name,temp1.employeeid, temp1.alletec_mifid, temp1.alletec_cityname,temp1.alletec_regionname
from (select MIF.alletec_ce1name,User1.employeeid,MIF.alletec_mifid, MIF.alletec_regionname, MIF.alletec_cityname from Filteredalletec_mif as MIF FULL OUTER JOIN FilteredSystemUser As User1 on MIF.alletec_ce1=User1.systemuserid
FULL OUTER JOIN FilteredBusinessUnit as BU ON User1.businessunitid=BU.businessunitid
where MIF.alletec_organisationname='Konica Minolta India' AND (MIF.alletec_cityname ='Delhi') AND
(MIF.alletec_regionname ='North') ) as temp1
)
select temp2.alletec_ce1name,temp2.employeeid, temp2.alletec_regionname,temp2.alletec_cityname, count(alletec_mifid) as MIFASSIGN,
Incident.alletec_casecalltypename
from temp2 Left Outer join FilteredIncident As Incident On Incident.alletec_serialnomif=temp2.alletec_mifid
group by temp2.alletec_ce1name,temp2.employeeid,temp2.alletec_mifid,temp2.alletec_regionname,temp2.alletec_cityname,
Incident.alletec_casecalltypename
now as with i got one temporary table. i wish to have one more temporary table so that can incorporate my last executable table values from temp2. do have a look if u can help for either. Thanks
Count up your parentheses, I think they are mismatched.
Your query amounts to
select
*
from
(table) as temp3
This isn't valid, you can't put the parentheses there. The extra level of nesting is broken. You either need to do something like:
select
*
from
table
or something like
select
*
from (
select
*
from
table
) as temp3
Your first query can probably be simplified to:
Select
*
From (
select
MIF.alletec_ce1name,
User1.employeeid,
MIF.alletec_mifid,
count (MIF.alltec_mifid) as MifAssign
from
Filteredalletec_mif as MIF
full outer join
FilteredSystemUser As User1
on MIF.alletec_ce1 = User1.systemuserid
full outer join
FilteredBusinessUnit as BU
on User1.businessunitid=BU.businessunitid
where
MIF.alletec_organisationname = 'Konica Minolta India' AND
MIF.alletec_cityname ='Delhi' AND
MIF.alletec_regionname ='North'
group by
MIF.alletec_mifid,
MIF.alletec_ce1name,
User1.employeeid
) as temp1
Inner Join
FilteredIncident As Incident
On Incident.alletec_serialnomif = Temp1.alletec_mifid;

How to combine 2 sql statements

I am trying to retrieve data for a client from an old database that they have. The data I need is a mix of these 2 sql statements. How would I combine them to get all the data from the enrol_stud table and Stud_Haddress table in the second statement.
Statement 1 - I want all the data from Enrol_Stud and Stud_Haddress included in statement 2
select enrol_stud.*, stud_haddress.*
from enrol_stud_forms
inner join enrol_stud on enrol_stud_forms.student_id = enrol_stud.student_id
Statement 2 I want the data from the 2 tables above included in the statement below.
SELECT contact.*, vsmc.*, concarer1.*, salcarer2.*, contact.firstname ||'
'||contact.surname as STUDENT, salcarer1.salutation as CARER1_TITLE, concarer1.firstname as CARER1_FIRSTNAME, concarer1.surname as CARER1_SURNAME, concarer1.email_address as CARER1_EMAIL, salcarer2.salutation as CARER2_TITLE, concarer2.firstname as CARER2_FIRSTNAME, concarer2.surname as CARER2_SURNAME, concarer2.email_address as CARER2_EMAIL
FROM get_currently_enroled_students ('now') gces
INNER JOIN student on gces.student_id = student.student_id
INNER JOIN contact on student.contact_id=contact.contact_id
INNER JOIN view_Student_mail_carers vsmc on student.student_id=vsmc.student_id
INNER JOIN contact concarer1 on vsmc.carer1_contact_id=concarer1.contact_id
INNER JOIN contact concarer2 on vsmc.carer2_contact_id=concarer2.contact_id
INNER JOIN salutation salcarer1 on concarer1.salutation_id=salcarer1.salutation_id
INNER JOIN salutation salcarer2 on concarer2.salutation_id=salcarer2.salutation_id
ORDER BY contact.surname, contact.firstname
I know it is in the joins, I just can't work out how to include them.
You can try like below, include the columns from first statement per post as well include the joins as pointed below
SELECT contact.*,
vsmc.*,
enrol_stud.*, <- here
stud_haddress.*, <-here
concarer1.*,
salcarer2.*,
contact.firstname ||' '||contact.surname as STUDENT,
salcarer1.salutation as CARER1_TITLE,
concarer1.firstname as CARER1_FIRSTNAME,
concarer1.surname as CARER1_SURNAME,
concarer1.email_address as CARER1_EMAIL,
salcarer2.salutation as CARER2_TITLE,
concarer2.firstname as CARER2_FIRSTNAME,
concarer2.surname as CARER2_SURNAME,
concarer2.email_address as CARER2_EMAIL
FROM get_currently_enroled_students ('now') gces
INNER JOIN enrol_stud_forms on gces.student_id = enrol_stud_forms.student_id <- here
INNER JOIN enrol_stud on enrol_stud.student_id = gces.student_id <- here
INNER JOIN student on gces.student_id = student.student_id
INNER JOIN contact on student.contact_id=contact.contact_id
INNER JOIN view_Student_mail_carers vsmc on student.student_id=vsmc.student_id
INNER JOIN contact concarer1 on vsmc.carer1_contact_id=concarer1.contact_id
INNER JOIN contact concarer2 on vsmc.carer2_contact_id=concarer2.contact_id
INNER JOIN salutation salcarer1
on concarer1.salutation_id=salcarer1.salutation_id
INNER JOIN salutation salcarer2
on concarer2.salutation_id=salcarer2.salutation_id
ORDER BY contact.surname, contact.firstname

Retrieve data from third table

This question is irritating to ask, as i haven't got the hang of using middle tables in sql yet. But i'm in a time rush so i've chosen to ask anyway.
I wish to combine these sql codes so i can retrieve the data from "teacher" aswell as "team" and "level", in the same repeater.
I'm catching a name from the "teacher" table through the FK_teacher from the middletable "teacher_team" which is related to my team table through FK_team
Would it by any chance be possible to combine these so i could extract it all through one repeater?
// Team <-> level relation
SELECT
team.team_id as team_id,
level.level as level,
FROM team
INNER JOIN level ON level.level_id = team.team_FK_level
WHERE team.team_FK_type = #id
// Team <-> Team_Teacher <-> Teacher relation
SELECT teacher.teacher_name as name
FROM teacher WHERE teacher.teacher_id
IN (
SELECT teacher_team.FK_teacher
FROM teacher_team
INNER JOIN team ON team.team_id = teacher_team.FK_team
WHERE team.team_FK_type = #id
)
* EDIT *
Got this code to work based on the answer of Ravi Singh. I've encountered another problem.
My repeater will output the teams row twice, if there are two teachers related to it in the teacher_teams (of course). Is there any way i could merge these without making a repeater inside a repeater?
SELECT
team.team_id as team_id,
level.level as level,
teacher_team.FK_teacher,
teacher.teacher_name as teacher
FROM team
INNER JOIN level ON level.level_id = team.team_FK_level
LEFT JOIN teacher_team on teacher_team.FK_hold = team.team_id
LEFT JOIN teacheron teacher.teacher_id = teacher_team.FK_teacher
WHERE team.team_FK_type = #id
Try this :
SELECT
teacher.teacher_name as name
,team.team_id as team_id
,level.level as level
FROM teacher
inner join teacher_team on teacher.teacher_id =teacher_team.FK_teacher
INNER JOIN team ON team.team_id = teacher_team.FK_team
INNER JOIN level ON level.level_id = team.team_FK_level
WHERE team.team_FK_type = #id
Update :
This should help with your updated question :
with demo_cte as(
SELECT
teacher.teacher_name as name
,team.team_id as team_id
,level.level as level
FROM teacher
inner join teacher_team on teacher.teacher_id =teacher_team.FK_teacher
INNER JOIN team ON team.team_id = teacher_team.FK_team
INNER JOIN level ON level.level_id = team.team_FK_level
WHERE team.team_FK_type = #id
)
select distinct t1.team_id,
t1.level,
STUFF(
(SELECT ', ' + t2.name
FROM demo_cte t2
where t1.team_id = t2.team_id
and t1.level = t2.level
FOR XML PATH (''))
, 1, 1, '') AS name
from demo_cte t1;