Join Tables using multiple fields across multiple tables - sql

I am trying to join tables based on multiple fields, one from the immediate table and one from an adjoined table.
I would like to join the "Equipment" to "Contract Detail" on ContractDetailID only if Equipment CustomerID = Contract CustomerID.
Thank you in advance

declare #contract as table(
contractid int,
customerid int
)
declare #contractDetail as table(
contractDetailId int,
ContractID int
)
declare #equipment as table(
equipmentId int,
contractDetailId int,
CustomerId int
)
insert into #contract values(5,3)
insert into #contractDetail values(10,5)
insert into #equipment values(1,10,3)
select e.*
from
#contract c inner join
#contractDetail cd on (c.contractId = cd.contractID) inner join
#equipment e on (c.customerId = e.CustomerId and e.contractDetailId = cd.contractDetailId)

Related

How can I pull data from multiple sql tables using a join statement

I'm designing a simple in-office ticket system, and would like to include a field for the party responsible for the next action. To do so right this moment I'm thinking of using tableName and tableID as specifiers for the specific responsible party (could be a technician, customer, or third party, all in different tables)
It would be fine to pull that data in and run another select call using the name of the table as a parameter, but the extra data flow slows things down significantly.
Is there a way to use a single join statement to return the details of the party with a column for the table name and one for the individual table id or is there a better way to store the data from multiple potential tables?
You can use left join to achieve your requirement :-
Set Nocount On;
Declare #OfficeTickets Table
(
Id Int Identity(1,1)
,Column1 Varchar(100)
,PartyType Varchar(1)
,TechnicianId Int Null
,CustomerId Int Null
,ThirdPartyId Int Null
)
Declare #OfficeTickets1 Table
(
Id Int Identity(1,1)
,Column1 Varchar(100)
,TableName Varchar(100)
,TableId Int Null
)
Declare #Technician Table
(
Id Int Identity(1,1)
,TechnicianName Varchar(100)
)
Declare #Customers Table
(
Id Int Identity(1,1)
,CustomerName Varchar(100)
)
Declare #ThirdParty Table
(
Id Int Identity(1,1)
,ThirdPartyName Varchar(100)
)
Insert Into #Technician(TechnicianName) Values
('Technician_1')
,('Technician_2')
,('Technician_3')
Insert Into #Customers(CustomerName) Values
('Customer_1')
,('Customer_2')
,('Customer_3')
Insert Into #ThirdParty(ThirdPartyName) Values
('ThirdParty_1')
,('ThirdParty_2')
,('ThirdParty_3')
,('ThirdParty_4')
Insert Into #OfficeTickets(Column1,PartyType,TechnicianId,CustomerId,ThirdPartyId) Values
('ABC','T',3,Null,Null)
,('XYZ','C',Null,2,Null)
,('PUQ','P',Null,Null,4)
Insert Into #OfficeTickets1(Column1,TableName,TableId) Values
('ABC','Technician',3)
,('XYZ','Customers',2)
,('PUQ','ThirdParty',4)
---- taken separate columns for parties
Select ot.Id
,ot.Column1
,t.TechnicianName
,c.CustomerName
,tp.ThirdPartyName
From #OfficeTickets As ot
Left Join #Technician As t On ot.PartyType = 'T' And ot.TechnicianId = t.Id
Left Join #Customers As c On ot.PartyType = 'C' And ot.CustomerId = c.Id
Left Join #ThirdParty As tp On ot.PartyType = 'P' And ot.ThirdPartyId = tp.Id
---- by TableName and TableId
Select ot.Id
,ot.Column1
,t.TechnicianName
,c.CustomerName
,tp.ThirdPartyName
From #OfficeTickets1 As ot
Left Join #Technician As t On ot.TableName = 'Technician' And ot.TableId = t.Id
Left Join #Customers As c On ot.TableName = 'Customers' And ot.TableId = c.Id
Left Join #ThirdParty As tp On ot.TableName = 'ThirdParty' And ot.TableId = tp.Id
output:-

Create T-SQL Function with table parameter

I needed to write function with table parameter.
an example:
CREATE FUNCTION getParentByBrandList
( #_BrandList TABLE(
BR_ID INT, BR_Name NVARCHAR(150), BR_ParentBrandID INT, BR_MasterBrandID INT, BR_Role INT,
BR_State INT, BR_OwnerID INT, BR_OwnerIP NVARCHAR(50), BR_CreateDate DATETIME, BR_UpdaterID INT,
BR_UpdaterIP NVARCHAR(50), BR_UpdateDate DATETIME
)
)
How can I do?
Thanx
Beginning from SQL Server 2008 you can use table valued parameters:
CREATE TYPE [dbo].[TableType] AS TABLE(
[ID] [INT] NULL
)
GO
CREATE FUNCTION fnTest
(
#t [dbo].[TABLETYPE] READONLY
)
RETURNS INT
AS
BEGIN
RETURN (SELECT TOP 1 ID FROM #t ORDER BY id DESC)
END
GO
DECLARE #t [dbo].[TABLETYPE]
INSERT INTO #t
VALUES ( 1 ),
( 2 )
SELECT dbo.fnTest(#t) AS ID
Output:
ID
2
Check this tutorial
Example : Passing Table Valued Parameter to a function
/* CREATE USER DEFINED TABLE TYPE */
CREATE TYPE StateMaster AS TABLE
(
StateCode VARCHAR(2),
StateDescp VARCHAR(250)
)
GO
/*CREATE FUNCTION WHICH TAKES TABLE AS A PARAMETER */
CREATE FUNCTION TableValuedParameterExample(#TmpTable StateMaster READONLY)
RETURNS VARCHAR(250)
AS
BEGIN
DECLARE #StateDescp VARCHAR(250)
SELECT #StateDescp = StateDescp FROM #TmpTable
RETURN #StateDescp
END
GO
Try this...
CREATE FUNCTION getParentByBrandList ( )
RETURNS #_BrandList TABLE
(
BR_ID INT
,BR_Name NVARCHAR(150)
,BR_ParentBrandID INT
,BR_MasterBrandID INT
,BR_Role INT
,BR_State INT
,BR_OwnerID INT
,BR_OwnerIP NVARCHAR(50)
,BR_CreateDate DATETIME
,BR_UpdaterID INT
,BR_UpdaterIP NVARCHAR(50)
,BR_UpdateDate DATETIME
)
AS
BEGIN
--code to create/populate table
END;
You seem to be missing the returns, I have added the place-holder for the code. Also, since the name suggests Get By, you might be intensing to supply a parameter? if so, you just add to the parenthesis...
getParentByBrandList ( param)
This function is from AdevnrtureWorks2012 db from Microsoft which they provide for study purpose.
ALTER FUNCTION [dbo].[ufnGetContactInformation](#PersonID int)
RETURNS #retContactInformation TABLE
(
-- Columns returned by the function
[PersonID] int NOT NULL,
[FirstName] [nvarchar](50) NULL,
[LastName] [nvarchar](50) NULL,
[JobTitle] [nvarchar](50) NULL,
[BusinessEntityType] [nvarchar](50) NULL
)
AS
-- Returns the first name, last name, job title and business entity type for the specified contact.
-- Since a contact can serve multiple roles, more than one row may be returned.
BEGIN
IF #PersonID IS NOT NULL
BEGIN
IF EXISTS(SELECT * FROM [HumanResources].[Employee] e
WHERE e.[BusinessEntityID] = #PersonID)
INSERT INTO #retContactInformation
SELECT #PersonID, p.FirstName, p.LastName, e.[JobTitle], 'Employee'
FROM [HumanResources].[Employee] AS e
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = e.[BusinessEntityID]
WHERE e.[BusinessEntityID] = #PersonID;
IF EXISTS(SELECT * FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = v.[BusinessEntityID]
WHERE bec.[PersonID] = #PersonID)
INSERT INTO #retContactInformation
SELECT #PersonID, p.FirstName, p.LastName, ct.[Name], 'Vendor Contact'
FROM [Purchasing].[Vendor] AS v
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = v.[BusinessEntityID]
INNER JOIN [Person].ContactType ct
ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = #PersonID;
IF EXISTS(SELECT * FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = s.[BusinessEntityID]
WHERE bec.[PersonID] = #PersonID)
INSERT INTO #retContactInformation
SELECT #PersonID, p.FirstName, p.LastName, ct.[Name], 'Store Contact'
FROM [Sales].[Store] AS s
INNER JOIN [Person].[BusinessEntityContact] bec
ON bec.[BusinessEntityID] = s.[BusinessEntityID]
INNER JOIN [Person].ContactType ct
ON ct.[ContactTypeID] = bec.[ContactTypeID]
INNER JOIN [Person].[Person] p
ON p.[BusinessEntityID] = bec.[PersonID]
WHERE bec.[PersonID] = #PersonID;
IF EXISTS(SELECT * FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c
ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = #PersonID AND c.[StoreID] IS NULL)
INSERT INTO #retContactInformation
SELECT #PersonID, p.FirstName, p.LastName, NULL, 'Consumer'
FROM [Person].[Person] AS p
INNER JOIN [Sales].[Customer] AS c
ON c.[PersonID] = p.[BusinessEntityID]
WHERE p.[BusinessEntityID] = #PersonID AND c.[StoreID] IS NULL;
END
RETURN;
END;

How to use equal and not equal together in SQL Server

I have to select values from three tables. First table is sale_project_detail, the second table is design_project_detail, and the third table is design_designer.
sale_project_detail schema:
Id int,
Name nvarchar(50),
ShortDescription nvarchar(max)
design_project_assignment schema:
Id int,
DId int (It is foreign key of design_designer table),
SPId int (It is foreign key of sale_project_detail table),
AssignDateTime datetime,
DueDate date,
Status varchar(10)
design_designer schema:
Id int,
Name nvarchar(15)
Now, I have to select complete detail from sale_project_detail
where assign_project_detail.SPId <> sale_project_detail.Id,
and
Select design_designer(Name)
from design_designer
where design_designer.Id = assign_project_detail.DId
I am trying below code, but it is returning wrong result.
My code:
SELECT
sale_project_detail.*,
design_project_assignment.*,
design_designer.Name
FROM
sale_project_detail,
design_project_assignment,
design_designer
WHERE
NOT EXISTS(SELECT NULL
FROM design_project_assignment
LEFT JOIN design_designer ON design_designer.Id = design_project_assignment.DId
WHERE sale_project_detail.Id = design_project_assignment.SPId)
Thanks in advance.
Try this
SELECT
*
FROM
sale_project_detail as spd
inner join design_project_assignment dpa on dpa.spid <> spd.id
inner join design_designer dd on dd.id = dpa.did;

SQL - allow null value in WHERE but still return data based on other parameters

This one is a little hard for me to explain correctly so please bear with me.
I am trying to create a dynamic SQL query to allow users to input data for various parameters i am creating for the query. I have it running if all the parameters are filled in but i cannot figure out how to allow for one or any of these parameters to allow a null value and still return data based on the other parameters. For example, using the query info below, if i set the #Client Parameter to NULL, iwould want the same info to return for all clients instead of specifying 1 client. I would want a similar function for all of the other parameters except the date fields, as those would always be required.
The reason i want to allow for null values is the final product of this query, i am writing a report using Telerik in VS 2010 which will be deployed for my company to use. In telerik you can allow a parameter to be null at runtime. The goal is to make this report useful for various situations, basically making it so i dont have to write 100 different queries over the next year and also giving the user more control/access over what they need.
Is this possible in SQL?
here is what i have right now:
DECLARE #Product int
DECLARE #OrderDate1 datetime
DECLARE #OrderDate2 datetime
DECLARE #Status int
DECLARE #Queue int
DECLARE #Client int
SET #Product = 86
SET #OrderDate1 = '2012-09-01'
SET #OrderDate2 = '2012-11-30'
SET #Status = 80
SET #Queue = 0
SET #Client = 56156
SELECT
CAST(oi.OrderID AS VARCHAR(MAX))+'.'+CAST(oi.OrderItemID AS VARCHAR(MAX)) AS OrderNumber
,CASE WHEN p.Abbreviation IS NULL THEN NULL
ELSE p.Abbreviation END AS Product
,o.OrderDate
,v.ContactFirstName+' '+v.ContactLastName AS Vendor
,m.Description AS Status
,q.Description AS Queue
FROM
OrderItems oi
JOIN Orders o (NOLOCK) ON o.OrderID = oi.OrderID
JOIN Products p (NOLOCK) ON p.ProductID = oi.ProductID
JOIN Vendors v (NOLOCK) ON v.VendorID = oi.VendorID
JOIN Milestones m (NOLOCK) ON m.MilestoneID = oi.LastMilestoneID
JOIN Queues q (NOLOCK) ON q.QueueID = oi.QueueID
WHERE
oi.ProductID in (#Product)
and o.OrderDate BETWEEN #OrderDate1 and DATEADD(DD, 1, #OrderDate2)
and oi.LastMilestoneID in (#Status)
and oi.QueueID in (#Queue)
and o.ClientID in (#Client)
DDL:
CREATE TABLE OrderItems
(
OrderID int,
OrderItemID int,
ProductID int,
VendorID int,
LastMilestoneID int,
QueueID int
)
insert into OrderItems
Values(1234567, 1, 86, 105111, 80, 0)
CREATE TABLE Orders
(
OrderID int,
ClientID int,
OrderDate datetime
)
insert into orders
Values(1234567, 56156, '2012-11-08')
CREATE TABLE Products
(
ProductID int,
Abbreviation Varchar(20),
)
insert into products
Values(86, 'Product1')
CREATE TABLE Vendors
(
VendorID int,
ContactFirstName Varchar(20),
ContactLastName Varchar(20)
)
insert into vendors
Values(105111, 'john', 'doe')
CREATE TABLE Milestones
(
MilestoneID int,
Description Varchar(20)
)
insert into milestones
values(80, 'Status 1')
CREATE TABLE Queues
(
QueueID int,
Description Varchar(20)
)
insert into Queues
values(0, 'Queue1')
Since the parameters are single values, I'd use = rather than IN. A very simple approach which will work poorly for large tables is:
WHERE (#Product IS NULL OR oi.ProductID = #Product)
AND (#Status IS NULL OR oi.LastMilestoneID = #Status)
... etc
What you are trying to perform is what Erland Sommarskog terms as "dynamic search conditions". Read this article for all your options and the benefits/downsides of each.

INSERT from JOIN inserts null values

The need to insert values from 3 tables into another table called myTable. The required fields in myTable are:
[Id_student] int,
[id_subjects] int
[degrees] float
[st_Name] nvarchar(30)
[Id_Class] int
[Id_Group] int
[Class] nvarchar(15)
[group] nvarchar(15))` ..
I created the stored procedure below. But after viewing the table I found that only the passed parameters were saved! ie #Id_student , #id_subjects , #degrees. Can anyone explain what is wrong with this code?
CREATE storedprocedure mySp_myTable_insert
#Id_student int,
#id_subjects int,
#degrees int
as
DECLARE #st_Name nvarchar(30)
SELECT #st_Name = pst.st_Name FROM dbo.sudents AS pst where pst.id_student=#id_student ;
INSERT [myTable]
(
[Id_student],
[id_subjects],
[degrees],
[st_Name],
[Id_Class],
[Id_Group],
[Class],
[group]
)
(select
#Id_student,
#id_subjects,
#degrees,
#st_Name
,tc.Id_Class
,tg.Id_Group
,tc.Class
,tg.group
from dbo.subjects sbj
inner join tGroup tg
inner join tClass tc
on tc.Id_Class=tg.Id_Class
on sbj.Id_Group =tg.Id_Group
where sbj.id_subjects=#id_subjects)
I think you should drop the parentheses around the SELECT statement and fix the order of the join-on keywords/clauses.
Try this version:
CREATE storedprocedure mySp_myTable_insert
#Id_student int,
#id_subjects int,
#degrees int
as
DECLARE #st_Name nvarchar(30)
SELECT #st_Name = pst.st_Name FROM dbo.sudents AS pst where pst.id_student=#id_student ;
INSERT [myTable]
(
[Id_student],
[id_subjects],
[degrees],
[st_Name],
[Id_Class],
[Id_Group],
[Class],
[group]
)
select
#Id_student,
#id_subjects,
#degrees,
#st_Name
,tc.Id_Class
,tg.Id_Group
,tc.Class
,tg.group
from dbo.subjects sbj
inner join tGroup tg on sbj.Id_Group =tg.Id_Group
inner join tClass tc on tc.Id_Class=tg.Id_Class
where sbj.id_subjects=#id_subjects
GO