Pivoting without aggregation - sql-server

I'm trying to pivot without aggregation, and running into a bit of a wall.
Here's the sample T-SQL I'm trying to get to work:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
declare #joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into #joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max) =
stuff((select distinct ',' + quotename(OptionalFieldName) from #joined for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
select * into #tmp from #joined
-- just to see that it's returning the expected values (it does)
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
,row_number() over (partition by Id order by Id) RN
from #tmp -- this is the FROM clause in the below dynamic-sql query
declare #query as nvarchar(max) = '
select Id, Name, ' + #cols + '
from (select Id, Name, OptionalFieldName, OptionalFieldValue, row_number() over (partition by Id order by Id) RN from #tmp) src
pivot (max(OptionalFieldName) for RN in (' + #cols + ')) pvt';
execute(#query);
drop table #tmp;
SSMS is giving me 2 errors:
Msg 8114, Level 16, State 1, Line 4
Error converting data type nvarchar to bigint.
Msg 473, Level 16, State 1, Line 4
The incorrect value "Field1" is supplied in the PIVOT operator.
The "debug" select statement is returning this:
The article (link above) seemed very promising, however I can't seem to be able to get it to work. What am I doing wrong? Or is this article outright wrong and what I'm trying to do is impossble?
I've seen a number of similar SO questions, but either they involved all-numeric fields that could "just work" with aggregation, or they involved known columns that could be implemented as simple joins - I don't know what OptionalFieldName values I'm going to be selecting, and the OptionalFieldValue values are strings that simply can't be aggregated, at least AFAIK.

I'm a bit confused on why you are trying to trick this using row_number(). Even though you have string values, you can still aggregate it - you just need to use max or min to get the result.
I'd always recommend trying to write your query with hard-coded values first, especially when using PIVOT before even attempting to use dynamic SQL. I'm unsure why you can't just write the query this way:
select Id, Name, Field1, Field2, Field3
from
(
select
Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) d
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (Field1, Field2, Field3)
) piv;
See a Demo.
Then if you really need dynamic SQL, you would just write it:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
declare #joined table (Id int, Name nvarchar(50), OptionalFieldName nvarchar(50), OptionalFieldValue nvarchar(50));
insert into #joined
select
data.Id
,data.Name
,opt.Name
,opt.Value
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max);
set #cols = stuff((select distinct ',' + quotename(OptionalFieldName)
from #joined
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
select * into #tmp from #joined
DECLARE #query AS NVARCHAR(MAX)
set #query = 'SELECT Id, Name,' + #cols + '
from
(
select Id
,Name
,OptionalFieldName
,OptionalFieldValue
from #tmp
) x
pivot
(
max(OptionalFieldValue)
for OptionalFieldName in (' + #cols + ')
) p '
execute(#query);
See Demo. Both versions appear to give the result that you have requested.

EDIT: This answer is here only to show another way to accomplish this pivoting. The answer from #bluefeet is the best solution!
Hope I understand what you need right:
declare #optionalFields table (ParentId int, Name nvarchar(50), Value nvarchar(50));
insert into #optionalFields values (1, 'Field1', 'Foo');
insert into #optionalFields values (1, 'Field2', 'Bar');
insert into #optionalFields values (1, 'Field3', '42');
insert into #optionalFields values (2, 'Field1', 'Bar');
insert into #optionalFields values (2, 'Field2', 'Foo');
insert into #optionalFields values (2, 'Field3', '24');
declare #data table (Id int, Name nvarchar(50));
insert into #data values (1, 'Test record 1');
insert into #data values (2, 'Test record 2');
select
data.Id
,data.Name
,opt.Name as Name1
,opt.Value into #tmp
from #data data
inner join #optionalFields opt on data.Id = opt.ParentId
declare #cols as nvarchar(max) =
stuff((select distinct ',' + quotename(Name1) from #tmp for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
DECLARE #cols1 as nvarchar(max) =
stuff((select distinct +',MAX(CASE WHEN (pvt1.'+quotename(Name1) +' = ros.RN AND pvt1.id = ros.id) THEN ros.Value ELSE NULL END) as '+quotename(Name1) from #tmp for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '');
declare #query as nvarchar(max) = '
;WITH cte AS(
SELECT * FROM #tmp
),
ros AS (
SELECT ROW_NUMBER() OVER (partition by Id order by Id) AS [RN],id,Value
FROM cte),
pvt1 AS (
select *
from (select Id, Name, Name1, row_number() over (partition by Id order by Id) RN
from cte) src
pivot (max(RN) for Name1 in ('+#cols+')) pvt)
SELECT pvt1.ID,
pvt1.Name,
'+#cols1+'
FROM pvt1
CROSS JOIN ros
GROUP BY pvt1.ID,
pvt1.Name'
execute(#query);
drop table #tmp
Result:
ID Name Field1 Field2 Field3
1 Test record 1 Foo Bar 42
2 Test record 2 Bar Foo 24
And if you add more Fields like insert into #optionalFields values (2, 'Field4', '15');, you will get:
ID Name Field1 Field2 Field3 Field4
1 Test record 1 Foo Bar 42 NULL
2 Test record 2 Bar Foo 24 15

Related

Passing multiple values into variable

I'm trying to pass a value from a table into a variable which I can then use in a query. The problem is that I need the variable to have multiple values, which I've never done before. Below is an example of what I'm trying to do.
CompanyID has multiple values for control number. How would I be able to pass multiple values into the variable? The query I'm using is using Open Query so I can't join to a temp table.
declare #t table( companyid int, control_number int)
insert into #t
values(5555, 777),
(5555, 720),
(5555, 234),
(111, 345),
(111, 356)
select *
from #t
declare #CN int
set #CN = (select control_number from #t where companyid = 5555)
select *
from #table
where control_number IN(#CN)
Instead of setting it into variable you can directly use it IN like this :
declare #t table( companyid int, control_number int)
insert into #t
values(5555, 777),
(5555, 720),
(5555, 234),
(111, 345),
(111, 356)
select *
from #t
select *
from #table
where control_number IN(select control_number from #t where companyid = 5555)
Try this out I haven't able to run this because you haven.t shared schema of #table
Another way to skin the cat. Make your second variable a table variable. Then just join to it.
declare #CN table (cntNbr int)
insert #CN (cntNbr)
select control_number from #t where companyid = 5555;
select t.*
from #t as t
join #CN as c
on c.cntNbr = t.control_number;
Rextester link: https://rextester.com/SCYCX42852
Method 1 (Dynamic SQL):
CREATE TABLE #temp ( companyid INT, control_number INT )
INSERT INTO #temp
VALUES (5555, 777),
(5555, 720),
(5555, 234),
(111, 345),
(111, 356)
SELECT * FROM #temp
DECLARE #controlNum VARCHAR(MAX)
SELECT #controlNum = ISNULL(#controlNum + ', ', '') + CAST(control_number AS VARCHAR) FROM #temp WHERE companyid = 5555
DECLARE #sql NVARCHAR(MAX) = 'SELECT * FROM #temp WHERE control_number IN ( ' + #controlNum + ')'
EXEC sp_executesql #sql
Method 2:
DECLARE #temp TABLE( companyid INT, control_number INT )
INSERT INTO #temp
VALUES (5555, 777),
(5555, 720),
(5555, 234),
(111, 345),
(111, 356)
SELECT * FROM #temp
SELECT * FROM #temp WHERE control_number IN (SELECT control_number FROM #temp WHERE companyid = 5555)

A help In the Pivot Method

Help In the pivot method , i dont want to keep writing all the Id is there a way to Like Do it without writing all the id
I dont know how
SELECT 'Montant' AS IdClient,
*
FROM
(
SELECT MontantTransaction,IdClient
FROM Transactions
) AS TableSource
PIVOT
(
Sum(MontantTransaction)
FOR IdClient IN( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24])
) AS TableDePivot;
i expect to see this code without the ( [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13]....
Try this -
Sample Temp Table & Data
Create Table #Transactions
(
IdClient varchar(3),
MontantTransaction decimal(10,2)
)
insert into #Transactions values (1, 1000.00)
insert into #Transactions values (1, 200.00)
insert into #Transactions values (2, 800.00)
insert into #Transactions values (2, 700.00)
insert into #Transactions values (3, 1100.00)
insert into #Transactions values (4, 1400.00)
Query
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT distinct ',' + QUOTENAME(c.IdClient)
FROM #Transactions c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set #query = 'SELECT ''Montant'' AS IdClient, ' + #cols + ' from
(
select
MontantTransaction
, IdClient
from #Transactions
) x
pivot
(
Sum(MontantTransaction)
for IdClient in (' + #cols + ')
) p '
execute(#query)
drop table #Transactions

Concatenating Value in Update

Ok, I have been banging my head against the wall for about 20 minutes and I can't seem to figure this one out. I have two tables each with a common field (ID) and what I want to do is to concatenate the values form #T2's UDValue column into #T1's UDValue column
CREATE TABLE #T1(ID INT, UDValue NVARCHAR(50))
CREATE TABLE #T2(ID INT, UDValue NVARCHAR(50))
INSERT INTO #T1(ID)
VALUES(1)
INSERT INTO #T2(ID, UDValue)
VALUES(1, 'Tom')
,(1, 'Dick')
,(1, 'Harry')
,(2, 'Chevy')
,(3, 'Apple')
,(2, 'Ford')
UPDATE #T1
SET UDValue = COALESCE(t1.UDValue, '') + t2.UDValue + ','
FROM
#T1 AS t1
INNER JOIN #T2 AS t2 ON t2.ID = t1.ID
SELECT * FROM #T1
DROP TABLE #T1
DROP TABLE #T2
So what I am looking for is to see my data like this:
ID UDValue
1, Tom,Dick,Harry
2, Chevy,Ford
3, Apple
but this is what I am getting:
ID UDValue
1 Tom,
2 Chevy,
3 Apple,
I want to avoid having to loop through each row but I don't see any alternatives.
you can use stuff with for xml path to concatenate column values
you can use a corelated sub query to get the comma separated values
Also it is not a good idea to store it as comma separated values in the database.
;with cte
as
(
select ID,
stuff((select ','+ T2.UDValue
from #T2 T2
where T2.ID = T1.ID
FOR XML PATH ('')), 1,1,'') as NewValue
from #T1 T1
)
update #T1
set UDValue = cte.NewValue
from cte
join #T1
on cte.ID = #T1.ID
select * from #T1
Concatenating Value in Update:
create table #T (Id int, Value varchar(50), primary key (Id, value));
declare #Id int;
declare #Value varchar(500);
insert into #T
( Id , Value )
values
( 1 , 'Tom' ),
( 1 , 'Dick' ),
( 1 , 'Harry' ),
( 2 , 'Chevy' ),
( 3 , 'Apple' ),
( 2 , 'Ford' );
update #T set
#Value = case when #Id is null or #Id = Id then #Value else null end,
#Value = Value = coalesce(#Value + ', ', '') + Value,
#Id = Id;
select Id, max(Value) from #T group by Id;
drop table #T;
The example works only if "primary key" is defined on the table.
More about "Quirky Update" is in Solving the Running Total and Ordinal Rank Problems
This is what I have come up with so far but I am not sure that it is the most efficient way to do this:
CREATE TABLE #T1(ID INT, UDValue NVARCHAR(50))
CREATE TABLE #T2(ID INT, UDValue NVARCHAR(50))
INSERT INTO #T1(ID)
VALUES(1)
,(2)
,(3)
INSERT INTO #T2(ID, UDValue)
VALUES(1, 'Tom')
,(1, 'Dick')
,(1, 'Harry')
,(2, 'Chevy')
,(3, 'Apple')
,(2, 'Ford')
DECLARE #id INT = 1, #UDValue NVARCHAR(MAX)
WHILE(#ID < 4)
BEGIN
SELECT #UDValue = STUFF((SELECT DISTINCT N',' + UDValue
FROM
#T2
WHERE ID = #ID
ORDER BY N',' + UDValue
FOR XML PATH(''), TYPE
).value(N'.[1]',N'nvarchar(max)'),1,1,'');
UPDATE #T1
SET UDValue = #UDValue
FROM
#T1 AS t1
WHERE
t1.ID = #ID
SELECT #ID += 1
END
SELECT * FROM #T1
DROP TABLE #T1
DROP TABLE #T2

How to filter records when filter is a comma separated list of values

I have a table which has a column in it containing a string of comma separated values (CSV).
e.g. VALUE1, VALUE2, VALUE3
Being passed in as a filter is another set of CSV.
e.g. VALUE2, VALUE3
So in the example above, the query should return any records where any of the filter values are in the CSV column.
Example
declare #table table
(
rownum int,
csv nvarchar(300)
)
insert into #table values (1,'VALUE1, VALUE2, VALUE3')
insert into #table values (2,'VALUE1, VALUE2')
insert into #table values (3,'VALUE1, VALUE3')
insert into #table values (4,'VALUE3, VALUE4')
insert into #table values (5,'VALUE1, VALUE2, VALUE3')
insert into #table values (6,'VALUE3, VALUE4, VALUE2')
insert into #table values (7,'VALUE3')
declare #Filter nvarchar(50)
set #Filter = 'VALUE1,VALUE2'
select * from #table
So in the example above, rows 1, 2, 3, 5 and 6 should be returned by a query as they all contain either VALUE1 or VALUE2.
If I well understood it, this will solve it:
You create a function to do the split:
CREATE FUNCTION [dbo].[ufn_CSVToTable] ( #StringInput VARCHAR(8000), #Delimiter nvarchar(1))
RETURNS #OutputTable TABLE ( [String] VARCHAR(10) )
AS
BEGIN
DECLARE #String VARCHAR(10)
WHILE LEN(#StringInput) > 0
BEGIN
SET #String = LEFT(#StringInput,
ISNULL(NULLIF(CHARINDEX(#Delimiter, #StringInput) - 1, -1),
LEN(#StringInput)))
SET #StringInput = SUBSTRING(#StringInput,
ISNULL(NULLIF(CHARINDEX(#Delimiter, #StringInput), 0),
LEN(#StringInput)) + 1, LEN(#StringInput))
INSERT INTO #OutputTable ( [String] )
VALUES ( #String )
END
RETURN
END
GO
Then you can do this:
declare #table table
(
rownum int,
csv nvarchar(300)
)
insert into #table values (1,'VALUE1, VALUE2, VALUE3')
insert into #table values (2,'VALUE1, VALUE2')
insert into #table values (3,'VALUE1, VALUE3')
insert into #table values (4,'VALUE2, VALUE3')
insert into #table values (5,'VALUE1, VALUE2, VALUE3')
insert into #table values (6,'VALUE3, VALUE1, VALUE2')
insert into #table values (7,'VALUE2, VALUE1')
declare #Filter nvarchar(50)
set #Filter = 'VALUE3,VALUE4'
select * from #table
SELECT * INTO #FilterTable FROM ufn_CSVToTable(#Filter, ',')
SELECT * FROM #FilterTable
select * from #table where EXISTS(SELECT String FROM #FilterTable WHERE csv like '%' + String + '%')
DROP TABLE #FilterTable
I'm considering the description "return any rown containing any of the calues in the filter"
You can use the PatIndex to find out the pattern in the field. Like the Following :
SELECT * FROM #TABLE WHERE PATINDEX('%'+#FILTER+'%',CSV)>0
What about this now? I didn't have used any User defined functions at all.
declare #table table
(
rownum int,
csv nvarchar(300)
)
insert into #table values (1,'VALUE1,VALUE2,VALUE3')
insert into #table values (2,'VALUE1,VALUE2')
insert into #table values (3,'VALUE1,VALUE3')
insert into #table values (4,'VALUE2,VALUE3')
insert into #table values (5,'VALUE1,VALUE2,VALUE3')
insert into #table values (6,'VALUE3,VALUE1,VALUE2')
insert into #table values (7,'VALUE2,VALUE1')
DECLARE #FILTER VARCHAR(50)
DECLARE #IN VARCHAR(MAX)
SET #FILTER='VALUE1,VALUE2'
SET #IN=REPLACE(#FILTER,',','%')
SET #IN='%'+#IN+'%'
SELECT #IN
SELECT * FROM #table WHERE PATINDEX(#IN,RTRIM(LTRIM(CSV))) >0
Try this one -
DECLARE #table TABLE (rownum INT, csv NVARCHAR(300))
INSERT INTO #table
VALUES
(1,'VALUE1, VALUE2, VALUE3')
, (2,'VALUE1, VALUE2')
, (3,'VALUE1, VALUE3')
, (4,'VALUE2, VALUE3')
, (5,'VALUE1, VALUE2, VALUE3')
, (6,'VALUE3, VALUE1, VALUE2')
, (7,'VALUE2, VALUE1')
DECLARE #Filter NVARCHAR(50)
SELECT #Filter = 'VALUE1,VALUE2'
;WITH cte AS
(
SELECT token = SUBSTRING(
t.string
, n.number + 1
, ABS(CHARINDEX(',', t.string, n.number + 1) - n.number - 1))
FROM ( SELECT string = ',' + #Filter ) t
CROSS JOIN [master].dbo.spt_values n
WHERE n.[type] = 'p'
AND n.number <= LEN(t.string)
AND SUBSTRING(t.string, n.number, 1) = ','
)
SELECT DISTINCT rownum, csv
FROM cte
JOIN #table ON PATINDEX('%'+ token +'%', CSV) = 0
I just modified #JoseTeixeira code using STRING_SPLIT function.
declare #table table
(
rownum int,
csv nvarchar(300)
)
insert into #table values (1,'VALUE1, VALUE2, VALUE3')
insert into #table values (2,'VALUE1, VALUE2')
insert into #table values (3,'VALUE1, VALUE3')
insert into #table values (4,'VALUE2, VALUE3')
insert into #table values (5,'VALUE1, VALUE2, VALUE3')
insert into #table values (6,'VALUE3, VALUE1, VALUE2')
insert into #table values (7,'VALUE2, VALUE1')
declare #Filter nvarchar(50)
set #Filter = 'VALUE3,VALUE4'
--select * from #table
select * from #table where EXISTS(SELECT [value] FROM string_split(#Filter, ',')
WHERE csv like '%' + [value] + '%') -- Table with filtered records

How to make row data comma separated in SQL?

I am having one query which returns me following output.
(No of results not same all time, means sometimes it gives 3 category,sometimes 8 category etc..)
CategoryName
Test1
Test2
Test3
Now i want that store procedure should return me these date in comma separated format.
e.g. output string should be like: Test1,Test2,Test3
Can you please tell me how can i achieve this?
this will work for all characters in your data:
set nocount on;
declare #YourTable table (BirthDay datetime, PersonName varchar(20))
insert into #YourTable VALUES ('1-10-2010', 'Joe' )
insert into #YourTable VALUES ('2-10-2010', 'Bob <&>' )
insert into #YourTable VALUES ('2-10-2010', 'Alice')
set nocount off
--Concatenation with FOR XML and eleminating control/encoded character expansion "& < >"
SELECT
p1.BirthDay
,STUFF(
(SELECT
', ' + p2.PersonName
FROM #YourTable p2
WHERE p2.BirthDay=p1.BirthDay
ORDER BY p2.PersonName
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS PersonNames
FROM #YourTable p1
GROUP BY p1.BirthDay
OUTPUT:
BirthDay PersonNames
----------------------- ------------------------
2010-01-10 00:00:00.000 Joe
2010-02-10 00:00:00.000 Alice, Bob <&>
(2 row(s) affected)
Try COALESCE or ISNULL:
DECLARE #returnValue varchar(MAX)
SELECT
#returnValue = COALESCE(#returnValue + ', ', '') + CategoryName
FROM
TableName
Have a look at something like (Full working example)
DECLARE #Table TABLE(
ID INT,
Val VARCHAR(50)
)
INSERT INTO #Table (ID,Val) SELECT 1, 'A'
INSERT INTO #Table (ID,Val) SELECT 1, 'B'
INSERT INTO #Table (ID,Val) SELECT 1, 'C'
INSERT INTO #Table (ID,Val) SELECT 2, 'B'
INSERT INTO #Table (ID,Val) SELECT 2, 'C'
--Concat
SELECT t.ID,
STUFF((
SELECT ',' + t1.Val
FROM #Table AS t1
WHERE t1.ID = t.ID
FOR XML PATH('')
), 1, 1, '')
FROM #Table t
GROUP BY t.ID
Also, you might find that Googling will provide a lot of answers.
One means:
SELECT STUFF((
SELECT ',' + CategoryName AS [text()]
FROM YourTable
FOR XML PATH('')
), 1, 1, '')
...but watch out for XML entities that will be escaped up - e.g. & => &
Just modify the KM answer in a store procedure
ALTER Procedure [dbo].[Payroll_rptAbsentReport]
#FromDate DateTime,
#ToDate DateTime,
#GFacatoryID UniqueIdentifier
As
Begin
-- Temporary table for Row data seperation
CREATE TABLE TestTable(GEmployeeGenInfoID uniqueidentifier, dtAttendDateTime varchar(max))
INSERT INTO
TestTable(GEmployeeGenInfoID, dtAttendDateTime)
SELECT
Payroll_tblAttendance.GEmployeeGenInfoID
,CONVERT(VARCHAR(max), dtAttendDateTime, 105)dtAttendDateTime
FROM Payroll_tblAttendance
INNER JOIN PIS.dbo.PIS_tblEmployeeGenInfo as EmployeeGenInfo ON Payroll_tblAttendance.GEmployeeGenInfoID= EmployeeGenInfo.GEmployeeGenInfoID
WHERE Payroll_tblAttendance.DayStatusID = 0 AND EmployeeGenInfo.GFactoryID=#GFacatoryID AND Payroll_tblAttendance.dtAttendDateTime Between #FromDate and #ToDate ORDER BY dtAttendDateTime
-- Final expected output
SELECT DISTINCT
EmployeeGenInfo.StrEmpName
,EmployeeGenInfo.StrEmpID
,Attendence.CardNo
,EmployeeDesignation.StrDesignationName
,EmployeeDept.StrDepartmentName
-- Count data will be in one column
,(Select COUNT(*) From TestTable Where GEmployeeGenInfoID=Attendence.GEmployeeGenInfoID) TotalAbsent
-- Row data set into one column seperate by coma
,substring( ( SELECT ', ' + dtAttendDateTime as [text()]
FROM TestTable
WHERE GEmployeeGenInfoID = Attendence.GEmployeeGenInfoID
FOR XML path(''), elements
), 3, 1000
) List
FROM
Payroll_tblAttendance as Attendence
INNER JOIN TestTable on TestTable.GEmployeeGenInfoID=Attendence.GEmployeeGenInfoID
INNER JOIN PIS.dbo.PIS_tblEmployeeGenInfo as EmployeeGenInfo ON Attendence.GEmployeeGenInfoID= EmployeeGenInfo.GEmployeeGenInfoID
INNER JOIN PIS.dbo.PIS_tblDesignationInfo as EmployeeDesignation ON EmployeeGenInfo.GDesignationInfoID= EmployeeDesignation.GDesignationInfoID
INNER JOIN PIS.dbo.PIS_tblDepartment as EmployeeDept ON EmployeeGenInfo.GDepartmentID= EmployeeDept.GDepartmentID
WHERE EmployeeGenInfo.GFactoryID=#GFacatoryID AND Attendence.DayStatusID = 0 AND Attendence.dtAttendDateTime Between #FromDate and #ToDate
DROP TABLE TestTable
END

Resources