INSERT from JOIN inserts null values - sql

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

Related

How to capture columns from joined tables using output clause?

I am updating a table called tableA by joining tableB and tableC at the same time I am capturing updated records into temp table using output clause from tableA . Now I want capture columns from table B for the updated data but output clause isn't allowing the same.
Eg:
Update SLC Set SLC.Datascrublevel = C.Datascrublevel
OUTPUT [Deleted].Systemcode,
[Deleted].Systemkey,
[Deleted].datascrublevel,
[Inserted].datascrublevel
INTO #TEMP1
FROM TABLEA SLC with(nolock)
INNER JOIN TABLEB SC ON SC.SystemCode = SLC.SystemCode
INNER JOIN TABLEC SL ON SL.SystemCode = SLC.SystemCode and SLC.SystemKey = SL.Systemkey
INNER JOIN #TEMP C ON SLC.Datascrublevel <> C.DataScrubLevel AND C.Systemcode = SLC.SystemCode and C.Systemkey = SLC.SystemKey
Now I want columns from tableB to capture into temp table using output clause. Please provide your advise if there are any alternative ways.
Just Like you have given it as [deleted].[Column Name] and [Inserted].[Column Name] add one more column as [SC].[Column Name]
Example :
IF OBJECT_ID('TempDb..#TABLEA') IS NOT NULL
DROP TABLE #TABLEA
IF OBJECT_ID('TempDb..#TABLEB') IS NOT NULL
DROP TABLE #TABLEB
IF OBJECT_ID('TempDb..#TABLEC') IS NOT NULL
DROP TABLE #TABLEC
IF OBJECT_ID('TempDb..#TABLED') IS NOT NULL
DROP TABLE #TABLED
CREATE TABLE #TABLEA
(
SeqNo INT IDENTITY(1,1),
MyDate DATE
)
CREATE TABLE #TABLEB
(
SeqNo INT IDENTITY(1,1),
FullName VARCHAR(20)
)
CREATE TABLE #TABLEC
(
SeqNo INT IDENTITY(1,1),
FullName VARCHAR(20),
MyDate DATE
)
CREATE TABLE #TABLED
(
SeqNo INT,
MyDate DATE,
FullName VARCHAR(20)
)
INSERT INTO #TABLEA
(
MyDate
)
SELECT GETDATE()
UNION
SELECT GETDATE()+1
UNION
SELECT GETDATE()-1
INSERT INTO #TABLEB
(
FullName
)
VALUES('A'),('B'),('C')
INSERT INTO #TABLEC
(
FullName
)
VALUES('A'),('B'),('C')
UPDATE C
SET MyDate = A.MyDate
OUTPUT
deleted.SeqNo,
deleted.MyDate,
B.FullName
INTO #TABLED
FROM #TABLEC C
INNER JOIN #TABLEB B
ON C.FullName = B.FullName
INNER JOIN #TABLEA A
ON A.SeqNo = B.SeqNo
SELECT * FROM #TABLED

Join Tables using multiple fields across multiple tables

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)

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;

SQL join with previous row from the same group

I have a problem with sql query. I'm trying to create one time script which will put data to table. I have temporary table of new values ordered by date and i'm going to search previous value which have to have the same GroupId, TransactionId and FieldTypeId but ClaimModificationId have to be smaller.
Below i write a script which would be good if not error throwing on line:
where m2.ClaimModificationId < m1.ClaimModificationId
sql does not allow do referer to m1 table. Is there a method to write that condition differently?
create table #modifications (
[ClaimModificationId] INT IDENTITY(1,1),
[GroupId] INT,
[FieldTypeId] INT,
[FieldName] NVARCHAR(255),
[TransactionId] INT,
[NewValue] NVARCHAR(255),
[UserEmail] NVARCHAR(255),
[ModificationDate] DATETIME,
[Action] NVARCHAR(50))
select top 10
m1.[GroupId],
m1.[FieldTypeId],
m1.[FieldName],
m1.[TransactionId],
cm4.[NewValue] as OldValue,
m1.[NewValue],
m1.[UserEmail],
m1.[ModificationDate],
m1.[Action]
from #modifications m1
left join (
select max(m2.ClaimModificationId) as ClaimModificationId, m2.[GroupId], m2.[FieldTypeId], m2.TransactionId
from #modifications m2
where m2.ClaimModificationId < m1.ClaimModificationId
group by m2.GroupId, m2.FieldTypeId, m2.TransactionId) m3
on m3.groupId = m1.GroupId and m3.FieldTypeId = m1.FieldTypeId and m3.TransactionId = m1.TransactionId
LEFT JOIN #modifications cm4 ON m3.ClaimModificationId = cm4.ClaimModificationId
Try with OUTER APPLY:
SELECT TOP 10
m1.[GroupId] ,
m1.[FieldTypeId] ,
m1.[FieldName] ,
m1.[TransactionId] ,
cm4.[NewValue] AS OldValue ,
m1.[NewValue] ,
m1.[UserEmail] ,
m1.[ModificationDate] ,
m1.[Action]
FROM #modifications m1
OUTER APPLY ( SELECT MAX(m2.ClaimModificationId) AS ClaimModificationId ,
m2.[GroupId] ,
m2.[FieldTypeId] ,
m2.TransactionId
FROM #modifications m2
WHERE m2.ClaimModificationId < m1.ClaimModificationId
AND m2.groupId = m1.GroupId
AND m2.FieldTypeId = m1.FieldTypeId
AND m2.TransactionId = m1.TransactionId
GROUP BY m2.GroupId ,
m2.FieldTypeId ,
m2.TransactionId
) m3
LEFT JOIN #modifications cm4 ON m3.ClaimModificationId = cm4.ClaimModificationId
you can try something like this
create table #modifications
(
[ClaimModificationId] INT IDENTITY(1,1),
[GroupId] INT,
[FieldTypeId] INT,
[FieldName] NVARCHAR(255),
[TransactionId] INT,
[NewValue] NVARCHAR(255),
[UserEmail] NVARCHAR(255),
[ModificationDate] DATETIME,
[Action] NVARCHAR(50)
)
INSERT INTO #modifications values(1,1,'field',2,'new val1','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(1,2,'field',2,'val1','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(2,1,'field',3,'val2','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(1,1,'field',2,'val3','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(1,1,'field',2,'val4','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(1,1,'field',2,'val5','email#email.com',GETDATE(),'inserted')
INSERT INTO #modifications values(2,1,'field',3,'val5','email#email.com',GETDATE(),'inserted')
SELECT TOP 10
m1.[GroupId],
m1.[FieldTypeId],
m1.[FieldName],
m1.[TransactionId],
LAG([NewValue]) OVER(PARTITION by GroupId, FieldTypeId, TransactionId ORDER BY ClaimModificationId ASC) as OldValue,
m1.[NewValue],
m1.[UserEmail],
m1.[ModificationDate],
m1.[Action]
from #modifications m1