Vertical Join in an SQL Statement - sql

I've got the following SQL Statement:
select * from Leaves inner join LeaveDetails on Leaves.LeaveId= LeaveDetails.LeaveId
inner join Employee on Leaves.EmployeeCode = Employee.EmployeeCode
inner join LeaveType on Leaves.LeaveTypeId= LeaveType.LeaveTypeId
inner join LeaveStatus on Leaves.StatusId = LeaveStatus.StatusId
inner join Employee_organizationaldetails on Employee_organizationaldetails.EmployeeCode=Employee.EmployeeCode
where Leaves.LeaveId = 7295
Employee_organizationdetails contains another column called reporting officer which is a foreign key to the same Employee table. Now I need to get the name of the Employee.
How can I write the above query so that I can get the name of the reporting officer as another column without fetching executing the query
select (FirstName + ' ' + LastName) as name from Employee where EmployeeCode = ReportingTo
Here ReportingTo is the employee code. I need to join them vertically. Something similar to Union operator

You want to join back to another "copy" of the Employee table:
select *, (ro.FirstName + ' ' + LastName) as ReportingName
from Leaves inner join LeaveDetails on Leaves.LeaveId= LeaveDetails.LeaveId
inner join Employee on Leaves.EmployeeCode = Employee.EmployeeCode
inner join LeaveType on Leaves.LeaveTypeId= LeaveType.LeaveTypeId
inner join LeaveStatus on Leaves.StatusId = LeaveStatus.StatusId
inner join Employee_organizationaldetails on Employee_organizationaldetails.EmployeeCode=Employee.EmployeeCode left outer join
Employee ro
on ro.EmployeeCode = ReportingTo
where Leaves.LeaveId = 7295;
You probably don't want the * -- I assume it is just a shorthand for the question. It is better to list columns explicitly, especially because there are duplicate column names.

Possible this be helpful for you -
SELECT
*
, ReportingName = ro.FirstName + ' ' + LastName
FROM (
SELECT *
FROM dbo.Leaves l
WHERE l.LeaveId = 7295
) l
JOIN dbo.LeaveDetails ld ON l.LeaveId = ld.LeaveId
JOIN dbo.Employee e ON l.EmployeeCode = e.EmployeeCode
JOIN dbo.LeaveType lt ON l.LeaveTypeId = lt.LeaveTypeId
JOIN dbo.LeaveStatus ls ON l.StatusId = ls.StatusId
JOIN dbo.Employee_organizationaldetails e2 ON e2.EmployeeCode = e.EmployeeCode
LEFT JOIN dbo.Employee ro ON ro.EmployeeCode = ReportingTo

Related

While fetching data from 3 tables using join I get an error: Column 'semester' and 'department' in field list is ambiguous

All three table contains 'semester' and 'department' column
SELECT DISTINCT
test_name,
fname,
lname,
rno
FROM exam_attempted_list
INNER JOIN stud_test ON
exam_attempted_list.student_id = stud_test.student_id
INNER JOIN stud_reg ON
exam_attempted_list.student_id = stud_reg.student_id WHERE semester='2nd' AND department='cse'
Use the following format, i.e, there were some statements which were repeating in your query, missing aliases in statements:
SELECT DISTINCT exam_attempted_list.test_name ,exam_attempted_list.fname,
exam_attempted_list.lname , exam_attempted_list.rno
FROM exam_attempted_list
INNER JOIN stud_test
ON exam_attempted_list.student_id = stud_test.student_id
INNER JOIN stud_reg
ON exam_attempted_list.student_id = stud_reg.student_id
WHERE semester='2nd' AND department='cse'
Use table aliase like exam_attempted_list.semester='2nd'
SELECT DISTINCT test_name ,fname, lname ,rno
FROM
exam_attempted_list
INNER JOIN stud_test ON exam_attempted_list.student_id = stud_test.student_id
INNER JOIN stud_reg ON exam_attempted_list.student_id = stud_reg.student_id
WHERE exam_attempted_list.semester='2nd' AND exam_attempted_list.department='cse';
SELECT DISTINCT eal.test_name , eal.fname, eal.lname , eal.rno
FROM exam_attempted_list AS eal
INNER JOIN stud_test AS st ON eal.student_id = st.student_id
INNER JOIN stud_reg AS sr ON eal.student_id = sr.student_id
WHERE eal.semester='2nd' AND eal.department='cse'
Replace eal with either st or sr depending on where you want the data from.

PostgreSQL select multiple columns of a table that is connected via a many-to-many pivot

I have this query:
SELECT
a.account_uuid,
a.account_no,
a.account_group_uuid,
a.account_scope_uuid,
a.created_at,
a.deleted_at,
s.service_uuid,
s.status,
st.service_type,
(
SELECT
c.company
FROM companies c
WHERE a.company_owner_uuid = c.company_uuid
)
FROM
accounts a
LEFT JOIN
services s
ON a.account_uuid = s.account_uuid
LEFT JOIN
service_types st
ON s.service_type_uuid = st.service_type_uuid
WHERE
a.deleted_at IS NULL
ORDER BY
a.account_no
And I need to join and select multiple columns from a people table by way of a pivot table accounts_contacts that would have the account_uuid and a person_uuid. There are also is_primary and is_active columns on the accounts_contacts table and there will only be one primary at a time, so the end result would be a single first and last name. This is the idea of the query:
SELECT
p.first_name, p.last_name
FROM
people p
INNER JOIN
accounts_contacts ac
ON ac.account_uuid = a.account_uuid
AND ac.person_uuid = p.person_uuid
WHERE
ac.is_primary = true
AND ac.is_active = true
But not sure how to fit it into the above query. A subquery would only allow for one of the columns.
account_contacts is an "association" or "junction" table. It is not a pivot table.
The basic idea should be joins:
SELECT . . . ,
p.first_name, p.last_name
FROM accounts a LEFT JOIN
services s
ON a.account_uuid = s.account_uuid LEFT JOIN
service_types st
ON s.service_type_uuid = st.service_type_uuid LEFT JOIN
accounts_contacts ac
ON ac.account_uuid = a.account_uuid LEFT JOIN
people p
ON ac.person_uuid = p.person_uuid AND
ac.is_primary = true AND
ac.is_active = true

How do I use a table name that's returned in a select statement, in a join?

*Note: This is not the same as the "possible duplicate". Here, the table name will be different for each record returned in the SELECT statement. So I can't just "set" a variable like set #tableName = 'whatever'.
Here's my SQL - take a look at my last inner join. e.Name from the table EmailSendDefintion is the name of the table I need to join to. So, this is kind of dynamic, I know, but how do I join to a table that is stored in a field in another table?
select top 5000
x.HL_ACCT_ID as 'HL_ACCT_ID',
x.SALE_CODE as 'SALE_CODE',
s.SubscriberKey as 'EmailAddress',
o.EventDate as 'Opened',
c.EventDate as 'Clicked',
b.EventDate as 'Bounced'
from c100._sent s with (nolock)
inner join c100._job j with (nolock) on s.jobid = j.jobid
inner join emailsenddefinition e with (nolock) on e.customerkey = j.emailsenddefinition
left join c100._open o with (nolock) on o.jobid = s.jobid and o.subscriberkey = s.subscriberkey
left join c100._click c with (nolock) on c.jobid = s.jobid and c.subscriberkey = s.subscriberkey
left join c100._bounce b with (nolock) on b.jobid = s.jobid and b.subscriberkey = s.subscriberkey
inner join c100.[e.name] x with (nolock) on x.EmailAddress = s.SubscriberKey
where e.clientid = 100
Perhaps you could just create a view that outputs the union of all the e.name tables? Then join to the view.
In order to keep this short, let's say you have just 2 different tables whose name could be in the e.name column, SubscriberEmail1 and SubscriberEmail2.
Then you could create a view like this:
CREATE VIEW SubscriberEmailUnion
AS
SELECT
'SubscriberEmail1' as TableName,
HL_ACCT_ID,
SALE_CODE,
EmailAddress
FROM SubscriberEmail1
UNION
SELECT
'SubscriberEmail2' as TableName,
HL_ACCT_ID,
SALE_CODE,
EmailAddress
FROM SubscriberEmail2
GO
Note that each part of the view is adding the name of it's underlying table as a column. You can then change your final join to:
inner join SubscriberEmailUnion x with (nolock) on (
x.EmailAddress = s.SubscriberKey
AND x.TableName = e.Name
)
I'm personally most familiar with MS Sql Server so my sample uses that syntax. Should be easy enough to change to work with a different server if necessary though.
For performance you can then use whatever feature your DB has, indexed views etc.
How many tables do you have? If not too many one option would be to left join all of them
left join c100.table1 x1 on x1.EmailAddress = s.SubscriberKey and [e.name] = 'table1'
left join c100.table2 x1 on x2.EmailAddress = s.SubscriberKey and [e.name] = 'table2'
etc...
and then in the select
coalesce(x1.HL_ACCT_ID, x2.HL_ACCT_ID, etc...) as 'HL_ACCT_ID',

How to Get All Rows matched + Unmatched and Unmatched Rows Column Will be null

I am working on an university management system. This is my database diagram
Database Diagram
I am creating a search form using this query:
SELECT Distinct
TblStudentBioData.RegNo,
TblStudentBioData.First_NameUr + SPACE(1)+ TblStudentBioData.Middle_NameUr + SPACE(1) + TblStudentBioData.Last_NameUr AS Name,
TblStudentBioData.Father_NameUr,
Ay.AcademicYearName,
Smst.SemName,
TBLCOLLEGE.CollegeName,
CID.ClassName,
TblImages.Images,
TblStudentBioData.Student_ID,
TblImages.ImageId,
Ay.AcademicYearId,
Smst.SemesterId,
TblClassSchedule.ClassSchId
FROM
TblStudentBioData
LEFT JOIN
TblStudentDetail ON (TblStudentBioData.Student_ID = TblStudentDetail.Student_ID)
OR (TblStudentBioData.Student_ID != TblStudentDetail.Student_ID)
INNER JOIN
TBLCFGSEX AS sex ON TblStudentBioData.CfgSexId = sex.CfgSexId
INNER JOIN
TBLMARITALSTATUS ON TblStudentBioData.MaritalStatusId = TBLMARITALSTATUS.MaritalStatusId
INNER JOIN
TblStudentSubAss ON TblStudentDetail.StudentDetailID = TblStudentSubAss.StudentDetailID
INNER JOIN
TblSubAss ON TblSubAss.SubAssId = TblStudentSubAss.SubAssId
INNER JOIN
TblClassSchedule ON TblStudentDetail.ClassSchId = TblClassSchedule.ClassSchID
INNER JOIN
TableClass AS CID ON TblClassSchedule.ClassID = CID.ClassID
INNER JOIN
TblImages ON TblStudentBioData.ImageId = TblImages.ImageId
LEFT JOIN
TBLCOLLEGE ON CID.CollegeId = TBLCOLLEGE.CollegeID
INNER JOIN
TBLBLOODGROUP BG On TblStudentBioData.BloodID = BG.BloodId
INNER JOIN
tableSemAssigning SA On TblClassSchedule.SemAssId = Sa.SemAssId
INNER JOIN
TblAcademicYear AY On SA.AcademicYearId = AY.AcademicYearId
INNER JOIN
TableSemester Smst On Smst.SemesterId = Sa.SemesterId
and this query gives me the output like this
In the result the 5th row is not matching row.
My question: how to show null value in non matching row's columns which I mention in the image?
As far as I can tell it would be like this. Anything that relates directly to TblStudentBioData MIGHT be an an INNER JOIN (I cannot tell) but everything that relates to TblStudentDetail should be a left join.
Also be careful with any where clause that you don't override these left joins.
SELECT DISTINCT /* I hate distinct, there is probably a better way */
TblStudentBioData.RegNo
, TblStudentBioData.First_NameUr + SPACE(1) + TblStudentBioData.Middle_NameUr + SPACE(1) + TblStudentBioData.Last_NameUr AS Name
, TblStudentBioData.Father_NameUr
, Ay.AcademicYearName
, Smst.SemName
, TBLCOLLEGE.CollegeName
, CID.ClassName
, TblImages.Images
, TblStudentBioData.Student_ID
, TblImages.ImageId
, Ay.AcademicYearId
, Smst.SemesterId
, TblClassSchedule.ClassSchId
FROM TblStudentBioData
INNER JOIN TBLCFGSEX AS sex
ON TblStudentBioData.CfgSexId = sex.CfgSexId
INNER JOIN TBLMARITALSTATUS
ON TblStudentBioData.MaritalStatusId = TBLMARITALSTATUS.MaritalStatusId
INNER JOIN TblImages
ON TblStudentBioData.ImageId = TblImages.ImageId
INNER JOIN TBLBLOODGROUP BG
ON TblStudentBioData.BloodID = BG.BloodId
LEFT JOIN TblStudentDetail
ON (TblStudentBioData.Student_ID = TblStudentDetail.Student_ID)
LEFT JOIN TblStudentSubAss
ON TblStudentDetail.StudentDetailID = TblStudentSubAss.StudentDetailID
LEFT JOIN TblClassSchedule
ON TblStudentDetail.ClassSchId = TblClassSchedule.ClassSchID
LEFT JOIN TblSubAss
ON TblSubAss.SubAssId = TblStudentSubAss.SubAssId
LEFT JOIN TableClass AS CID
ON TblClassSchedule.ClassID = CID.ClassID
LEFT JOIN TBLCOLLEGE
ON CID.CollegeId = TBLCOLLEGE.CollegeID
LEFT JOIN tableSemAssigning SA
ON TblClassSchedule.SemAssId = SA.SemAssId
LEFT JOIN TblAcademicYear AY
ON SA.AcademicYearId = AY.AcademicYearId
LEFT JOIN TableSemester Smst
ON Smst.SemesterId = SA.SemesterId

HSQLDB v.2.3.0: USING predicate working as intended?

The following query when executed against snapshot 50 of HSQLDB 2.3.0 produces an error. The error message is "Error: duplicate column name in derived table: INST_ID"
SELECT c.lastname, to_date_string(c.dob), i.itag|| ': ' ||
m.mrn, to_date_string(en.dofs),
to_date_string(en.dols), pa.payertag,
y.dxname, d.icd9, d.icd10, d.icd10name,
to_datetime_string(s.dos), r.cpt, r.rxname, p.lastname || ', ' ||
p.firstname
FROM Encounters AS en
INNER JOIN Clients AS c USING ( cli_id )
INNER JOIN Client_MRNs AS m ON c.defmrn_id = m.mrn_id
INNER JOIN Institutions AS i USING ( inst_id )
INNER JOIN Payers AS pa USING ( payer_id )
INNER JOIN Encounter_DXs AS x USING ( enc_id )
INNER JOIN Diagnoses AS d USING ( dx_id )
INNER JOIN DXSynonyms AS y ON d.defsyn_id = y.syn_id
INNER JOIN Services AS s USING ( enc_id )
INNER JOIN RXCodes AS r USING ( rx_id )
INNER JOIN Providers AS p USING ( prov_id )
WHERE (s.dos >= 56453 AND s.dos < 56461)
ORDER BY c.lastname, en.dofs, s.dos;
However, when I execute the same query but replace all the USING predicates with ON ... = phrases it executes successfully:
SELECT c.lastname, to_date_string(c.dob), i.itag|| ': ' ||
m.mrn, to_date_string(en.dofs),
to_date_string(en.dols), pa.payertag,
y.dxname, d.icd9, d.icd10, d.icd10name,
to_datetime_string(s.dos), r.cpt, r.rxname, p.lastname || ', ' ||
p.firstname
FROM Encounters AS en
INNER JOIN Clients AS c ON c.cli_id = en.cli_id
INNER JOIN Client_MRNs AS m ON c.defmrn_id = m.mrn_id
INNER JOIN Institutions AS i ON i.inst_id = m.inst_id
INNER JOIN Payers AS pa ON pa.payer_id = en.payer_id
INNER JOIN Encounter_DXs AS x ON x.enc_id = en.enc_id
INNER JOIN Diagnoses AS d ON d.dx_id = x.dx_id
INNER JOIN DXSynonyms AS y ON d.defsyn_id = y.syn_id
INNER JOIN Services AS s ON s.enc_id = en.enc_id
INNER JOIN RXCodes AS r ON r.rx_id = s.rx_id
INNER JOIN Providers AS p ON p.prov_id = s.prov_id
WHERE (s.dos >= 56453 AND s.dos < 56461)
ORDER BY c.lastname, en.dofs, s.dos;
Is this working as intended? I like using USING because it results in less verbose, cleaner code. I won't include the DDL for the tables right now (but can), because the queries are big and involve many tables, but there are three tables that have INST_ID fields. One table has it as the primary key, and the other two have foreign keys to it. Really the only difference in the queries is "ON" vs "USING".
After the first join, there is one INST_ID from ENCOUNTERS. After the second join, there is an additional one from CLIENTS_MRNS. The third join fails because of this duplication.