SQL get sender due to value in table - sql-server

Hello Now I have 2 table .One of them is TEACHER, another INSTITUTE
I have a temp table #QUESTIONS. There are two row in this temp table
QuestionId,SenderType,SenderId
1,Teacher,475
2,Institute,1
Now if sender type is teacher i want to get teacher name and surname from TEACHER table,if sender type is institute i want to get institute name from INSTITUTE table
How can I do it ?
Thanks in advance

Lets try something different for this case. Look at the sample.
SELECT SENDERTYPE,Q.SENDERID,COALESCE(T.NAME,I.NAME) AS NAME,COALESCE(T.SURNAME,I.SURNAME) AS NAME FROM QUESTIONS Q
LEFT JOIN TEACHER T ON T.ID=Q.SENDERID AND Q.SENDERTYPE='TEACHER'
LEFT JOIN INSTITUTE I ON I.ID=Q.SENDERID AND Q.SENDERTYPE='INSTITUTE'

Use CASE Statement:
SELECT
Q.QuestionId,
Q.SenderType,
CASE Q.SenderType WHEN 'Teacher' THEN T.Name+ ' '+T.Surname ELSE I.Name END AS Name
FROM #tblQuestion Q
LEFT JOIN #tblTeacher T ON Q.SenderId=T.Id AND Q.SENDERTYPE='TEACHER'
LEFT JOIN #tblInstitute I ON Q.SenderId=I.Id AND Q.SENDERTYPE='INSTITUTE'

It can be achieved using UNION
SELECT q.SenderType ,
t.Name + ' ' + t.Surname Name
FROM #QUESTIONS q
JOIN TEACHER t ON q.SenderId = t.ID
WHERE q.SenderType = 'Teacher'
UNION ALL
SELECT q.SenderType ,
i.Name
FROM #QUESTIONS q
JOIN INSTITUTE i ON q.SenderId = i.ID
WHERE q.SenderType = 'Institute';

Related

Accessing a new table created after a join

I have joined select columns from 3 tables into a new table using the following:
SELECT A.ExternalID, A.UserDefinedXml.value('(Skin_Sheet/#Label)[1]', 'varchar(3)') AS SS, A.ServiceSiteUid, A.LastModifiedDate, A.PersonUid,
B.FirstName, B.LastName, B.PersonUid,
C.Name
FROM Patient A
INNER JOIN Person B ON B.PersonUid = A.PersonUid
INNER JOIN ListServiceSite C ON C.ServiceSiteUid = A.ServiceSiteUid
WHERE SS IS NOT NULL
ORDER By LastModifiedDate;
This all works but I'm not sure how to reference the column SS created from data extracted from the XML so I can only select the observations in which the value is "Yes" or "No". In R I would have created a new object but I'm not sure how SQL stores this new table if I don't specify what the table name is.
Side note, I did try to insert this into a new table but SQL wasn't letting me because, for some reason, the join resulted in PersonUid being duplicated.
Thank you in advance, I'm very, very new to SQL and trying to learn on the fly.
Conceptually WHERE comes before SELECT, so you need to push the query into a derived table subquery or Common Table Expression (CTE) to reference SS in a WHERE clause. EG
with q as
(
SELECT A.ExternalID, A.UserDefinedXml.value('(Skin_Sheet/#Label)[1]', 'varchar(3)') AS SS, A.ServiceSiteUid, A.LastModifiedDate, A.PersonUid,
B.FirstName, B.LastName, B.PersonUid,
C.Name
FROM Patient A
INNER JOIN Person B ON B.PersonUid = A.PersonUid
INNER JOIN ListServiceSite C ON C.ServiceSiteUid = A.ServiceSiteUid
)
SELECT *
FROM q
WHERE SS IS NOT NULL
ORDER By LastModifiedDate;
This will put your results into a temp table, and avoids the problem of having two columns with the same name:
SELECT
A.ExternalID
,SS = A.UserDefinedXml.value('(Skin_Sheet/#Label)[1]', 'varchar(3)')
,A.ServiceSiteUid
,A.LastModifiedDate
,PersonUid_A = A.PersonUid
,B.FirstName
,B.LastName
,PersonUid_B = B.PersonUid
,C.Name
INTO #TempResults
FROM Patient A
INNER JOIN Person B ON B.PersonUid = A.PersonUid
INNER JOIN ListServiceSite C ON C.ServiceSiteUid = A.ServiceSiteUid
WHERE SS IS NOT NULL
ORDER BY LastModifiedDate;

T-SQL Multiple Join on 1 Table

I'm currently working on a complex T-SQL query in MS SQL Server 2012. I basically retrieve a basic list of projects, holding the ProjectId as well as the StaffVersionId (it is possible that the Staff changes throughout the project, although I hope it won't be the case :P ).
CREATE TABLE #BasicProjects
(
ProjectId INT
, StaffVersionId INT
)
Next I need to join on the ProjectData Table to get the Title of the project as well as join on the Employee Table to get the FullName of the Employee.
SELECT [P].ProjectId
, [PD].Label AS Title
, [E].Lastname + '' '' + Firstname AS Manager
, [E].Lastname + '' '' + Firstname AS Contact
FROM #BasicProjects [P]
INNER JOIN [MySchema].[ProjectData] [PD] ON [PD].ProjectDataId = [P].ProjectDataId
INNER JOIN [MySchema].[Staff] [Y] ON [Y].StaffVersionId = [P].StaffVersionId AND [Y].StaffTypeId = 3 // Manager
INNER JOIN [MySchema].[Staff] [X] ON [X].StaffVersionId = [P].StaffVersionId AND [X].StaffTypeId = 2 // Contact
INNER JOIN [dbo].[Employee] [E] ON [E].EmployeeId = [Y].EmployeeId
INNER JOIN [dbo].[Employee] [E] ON [E].EmployeeId = [X].EmployeeId
The query is kind of hard, because I have 2 kinds of staff employees 3 = Manager, 2 = Contact.
When I run my query I'm getting this error:
The correlation name 'E' is specified multiple times in a FROM clause.
Do you know how to solve this error? Or perhaps some advises on how to improve this query?
Thanks a lot!
You need different aliases for each join (just like you did for Staff)
SELECT [P].ProjectId
, [PD].Label AS Title
, [YE].Lastname + ' ' + YE.Firstname AS Manager
, [XE].Lastname + ' ' + XE.Firstname AS Contact
FROM #BasicProjects [P]
INNER JOIN [MySchema].[ProjectData] [PD] ON [PD].ProjectDataId = [P].ProjectDataId
INNER JOIN [MySchema].[Staff] [Y] ON [Y].StaffVersionId = [P].StaffVersionId AND [Y].StaffTypeId = 3 // Manager
INNER JOIN [MySchema].[Staff] [X] ON [X].StaffVersionId = [P].StaffVersionId AND [X].StaffTypeId = 2 // Contact
INNER JOIN [dbo].[Employee] [YE] ON [YE].EmployeeId = [Y].EmployeeId
INNER JOIN [dbo].[Employee] [XE] ON [XE].EmployeeId = [X].EmployeeId

Dynamic SQL in SQL Server - how to?

My question is about dynamic SQL. I have two tables
customers (custid, fn_name, Ln_name)
vendors (vendor_id, Custid, ordernum, orderdate)
And also I have other tables
table (tableid(pk), name)
table_col (colid(pk), tableid(fk), colname)
table_keys (key_id, tableid, key_col_name)
Now if user selects any column from the table_col tables, dynamically I need to get column names and dynamically identify the join from the table_keys based on the name match.
Could be somethings like this
select
t.name
, c.colname
, case k.key_col_name when not null then 'X' else '' end as iskey
from table_col as c
left join table_keys as k on k.key_col_name = c.colname
inner join table as t on t.tableid = c.tableid
where t.name in ('customers', 'vendors');

employee attendance structure using 3 table left innerjoins

SELECT b.Device_Person_ID, a.Personal_id, Date1,
CASE WHEN b.Device_Person_id IS NOT NULL THEN 'A' ELSE 'P' END as Emp_Status
FROM Emp_setting a
LEFT OUTER JOIN (SELECT device_person_id, MAX(logDateTime) AS Date1 FROM tempDeviceLogs
GROUP BY device_person_id) b
ON a.personal_id = b.device_person_id
here i joined only two tables but i need to join 3 tables to show employee details with attendance with specific date.
Required output is
employeename device_person_id designation emptype status
'dbo.persons_profile table
[pesonal_id]
,[Emp_Code]
,[Title]
,[First_name]
,[Middle_name]
,[last_name]
,[Father_Husband_Name]
,[Dob]
,[Age]
,[gender]
,[Marital_status]
,[Nationality]
,[bloodGroup]
,[perAddress]
,[PerStreet]
,[PerLocation]
,[PerCity]
,[PerPincode]
,[CorAddress]
,[CorStreet]
,[CorLocation]
,[CorCity]
,[CorPincode]
,[LandlinePhone]
,[cellNo]
,[EmailId]
,[NosofDependendants]
,[Dependendants_details]
,[Emergency_FirstName]
,[Emergency_Middle_name]
,[Emergency_Last_name]
,[Emergency_WithRelation]
,[Emergency_PhoneNo]
,[Emergency_CellNo]
,[Emergency_emailId]
,[Office_PF_ac_no]
,[ESI_ac_no]
,[JoinedDate]
,[Photofile]
,[ReportTo]
,[Brief_Notes]
,[dateofTermination]
,[termination_note]
,[Print_Priority]
,[DeviceEmployeeID]
,[LogsPermitted]
,[Machin_install_id]
,[Designation]
,[Dept]
,[Section]
,[Groups]
,[EmpWorkingTypeT]'
dbo.tempDeviceLogs table
[LogsID]
,[Device_Person_id]
,[Device_id]
,[logDateTime]
,[logVerifyMode]
,[workCodeID]
,[Machin_install_id]
,[data_loaded_dt]
,[Inout]
dbo.Emp_setting table
[Empset_id]
,[personal_id]
,[DesignationID]
,[DivisionID]
,[Emp_status]
,[Emp_TypeId]
,[Dept_Id]
,[Group_Id]
,[NDIVGRP_CODE]
you need to write to join conditions for achieving what you required.
as an example:
SELECT a.<respective>_id, d.<respective>_title, s.<respective>_id
FROM Emp_setting a
INNER JOIN persons_profile s ON a.<respective>_id = s.<respective>_id
INNER JOIN Emp_setting d ON a.<respective>_id = d.<respective>_id
INNER JOIN tempDeviceLogs b ON s.<respective>_id = b.<respective>_id

Sql Select from another table (loop?)

My SQL skills aren't great hence the post.
I'm trying to get all the contact names based on a company out.
For example I have two statements:
Select Id, CompanyName, Address From Clients
Select ClientId, ContactName From Contacts
You may have many contacts to a single client
Result: (I need all the contact names in a single column)
ContactName Company Address
----------------------------------------
Johh, Steve 123 Comp 12345 Address
David,Mike, Sarah 44 Comp 111 Address
A working example would be very much appreciated.
SELECT DISTINCT (
SELECT ISNULL(ct.ContactName, '') + ', '
FROM dbo.Clients cl JOIN dbo.Contacts ct ON cl.Id = ct.ClientId
WHERE cl.ID = cl2.Id
FOR XML PATH('')) AS ContactName, CAST(cl2.Id AS nvarchar(7)) + ' ' + cl2.CompanyName AS Company, Address
FROM dbo.Clients cl2
ORDER BY 2
Demo on SQLFiddle
Firstly build all the Contact Names for a Company into a Single Column. Assuming the database to be SQL Server, I'm using a Common Table Expression to store the single column contact list. Once the CTE is built, join it with the Clients table to get the ContactNames. FOR XML is used to concatenate rows.
WITH CTEContactList(ClientID,ContactNames)
AS
(
SELECT c1.ClientID,
Names = SUBSTRING(( SELECT ', ' + c2.ContactName
FROM Contacts c2
WHERE c1.ClientID = c2.ClientID
FOR XML PATH ('')),3,8000 ))
FROM Contacts c1
GROUP BY c1.ClientID
)
SELECT
cl.ID,
cl.CompanyName,
cl.Address,
ctelist.ContactNames
FROM Clients cl
INNER JOIN CTEContactList ctelist
ON cl.ID = cteList.ClientID
Sounds like you need to do a table join.
Example: two tables here
1. Person
2. Orders
Query:
SELECT
Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders ON Persons.P_Id = Orders.P_Id
ORDER BY Persons.LastName
You didn't specify your DBMS, so I'm assuming PostgreSQL:
select string_agg(ct.contactName, ', '), cl.companyname, cl.address
from contacts ct
join clients cl on cl.id = ct.clientId
group by cl.companyname, cl.address

Resources