I want to concatenate column values with a separator and assign it to variable.
If column value is null, there's no need to add separator.
For example: A|B|C|D
If B is null A|C|D.
I tried with CONCAT function, but if B is null, it results in A||C|D
DECLARE #OldValue VARCHAR(8000);
SELECT #OldValue = CONCAT([FloorCode],'|',
[FloorName],'|',
[BuildingID],'|',
[HCMLocationCode],'|',
[IsActive])
FROM tblFloor_Master
WHERE FloorID = #FloorID;
#FloorID is an input parameter of SP
SELECT #OldValue = CONCAT('',
CASE WHEN [FloorCode] IS NULL THEN '' ELSE CONCAT([FloorCode],'|') END,
CASE WHEN [FloorName] IS NULL THEN '' ELSE CONCAT([FloorName],'|') END,
CASE WHEN [BuildingID] IS NULL THEN '' ELSE CONCAT([BuildingID],'|') END,
CASE WHEN [HCMLocationCode] IS NULL THEN '' ELSE CONCAT([HCMLocationCode],'|') END,
[IsActive])
FROM tblFloor_Master
WHERE FloorID = #FloorID;
You can try the following query.
create table tempTable (id int identity(1, 1),col1 char(1), col2 char(1), col3 char(1), col4 char(1))
insert into tempTable values ('A', NULL, 'C', 'D')
select * into #NewTable from(
select id, col1 as Value from tempTable where col1 is not null
union
select id, col2 as Value from tempTable where col2 is not null
union
select id, col3 as Value from tempTable where col3 is not null
union
select id, col4 as Value from tempTable where col4 is not null
)a
SELECT ID
,STUFF((SELECT '| ' + CAST(Value AS VARCHAR(10)) [text()]
FROM #NewTable
WHERE ID = t.ID
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,' ') List_Output
FROM #NewTable t
GROUP BY ID
The output is as shown below
ID List_Output
---------------
1 A| C| D
If you do not want to put space between values then you can try this
SELECT ID
,STUFF((SELECT '|' + CAST(Value AS VARCHAR(10)) [text()]
FROM #NewTable
WHERE ID = t.ID
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,'') List_Output
FROM #NewTable t
GROUP BY ID
In this case the output will be
ID List_Output
---------------
1 A|C|D
You can also try the below actual query using stored procedure
create table tblFloor_Master (FloorID int identity(1, 1),
FloorCode char(1),
FloorName char(1),
BuildingID char(1),
HCMLocationCode char(1))
insert into tblFloor_Master values ('A', NULL, 'C', 'D')
GO
--To create a procedure
create proc uspGetConcateValue
#FloorId int
as
BEGIN
select * into #tblFloor_Master from(
select FloorId, FloorCode as Value from tblFloor_Master where FloorCode is not null
union
select FloorId, FloorName as Value from tblFloor_Master where FloorName is not null
union
select FloorId, BuildingID as Value from tblFloor_Master where BuildingID is not null
union
select FloorId, HCMLocationCode as Value from tblFloor_Master where HCMLocationCode is not null
)a
SELECT FloorId
,STUFF((SELECT '|' + CAST(Value AS VARCHAR(10)) [text()]
FROM #tblFloor_Master
WHERE FloorId = t.FloorId
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,1,'') List_Output
FROM #tblFloor_Master t
where FloorID = #FloorId
GROUP BY FloorId
END
Live demo here - Live Demo
Should be simple as doing replace, replace || to | then replace ||| to | since the maximum number of | is 3.
DECLARE #OldValue VARCHAR(8000);
SELECT #OldValue = replace(replace(CONCAT([FloorCode],'|',
[FloorName],'|',
[BuildingID],'|',
[HCMLocationCode],'|',
[IsActive]),'||','|'),'|||','|')
FROM tblFloor_Master
WHERE FloorID = #FloorID;
SELECT
TRIM ('|' FROM
regexp_replace(
CONCAT('','|','COLB','|','','|','COLD','|','COLE')
,'[\|]+'
,'|'
,'g'
)
)
Related
How to automatically fill a column with spaces to a pre-determined length in update SQL sentence in SQL Server 2012?
I have a table with several columns like
Col1 NVARCHAR(10)
Col2 NVARCHAR(100)
Col3 NVARCHAR(200)
Col4 NVARCHAR(50)
and more.
If value of column is NULL or '', I update the column with spaces to a pre-determined length (the lenth of the column).
For Col3, if value is NULL or '', spaces to 200 blank space (' ')
if value has any characters, 'abcd', fill (pad right) to 200 blank spaces. Then, finally 4 not spaces characters and 196 spaces characteres.
For example, for Col1 has length 10.
1) Value = NULL , Col1 value = ' ' (10 spaces)
2) Value = '' , Col1 value = ' ' (10 spaces)
2) Value = 'abc' , Col1 value = 'abc ' (abc and 7 spaces)
How can I do that in the UPDATE SQL?
Maybe using
select column_name, data_type, character_maximum_length
from information_schema.columns
where table_name = 'myTable'
or
SELECT COL_LENGTH('Table', 'Column')
More in How to get the size of a varchar[n] field in one SQL statement?
Try the following, the LEFT is used to keep the length down to the column length, while the space ensures the field is filled with spaces:
create table test (col1 varchar(10), col2 varchar(15))
GO
insert into test (col1, col2)
values ('', '')
,(NULL, NULL)
,('abc', 'abc')
UPDATE test
SET col1 = LEFT(COALESCE(col1, '') + SPACE(COL_LENGTH('test', 'col1')), COL_LENGTH('test', 'col1'))
,col2 = LEFT(COALESCE(col2, '') + SPACE(COL_LENGTH('test', 'col2')), COL_LENGTH('test', 'col2'))
FROM test
SELECT *
FROM test
I don't understand what you want exactly, but here is what I understand:
CREATE TABLE MyTable (
Col1 NVARCHAR(200),
Col2 NVARCHAR(100),
Col3 NVARCHAR(200),
Col4 NVARCHAR(50)
);
INSERT INTO MyTable VALUES (NULL, NULL, NULL, NULL), ('ABC', NULL, NULL, NULL);
-- You can do the same for the other cols
UPDATE MyTABLE
SET Col1 = REPLICATE(' ', COL_LENGTH('MyTable', 'Col1')/2)
WHERE Col1 IS NULL;
SELECT *
FROM MyTable;
Demo
Update:
Here is how to do it in one statement:
UPDATE MyTABLE
SET Col1 = (SELECT CASE WHEN (Col1 IS NULL) OR (Col1 = '') THEN
REPLICATE(' ', COL_LENGTH('MyTable', 'Col1')/2)
ELSE Col1 + REPLICATE(' ', (COL_LENGTH('MyTable', 'Col1')/2)- LEN(Col1)) END),
Col2 = (SELECT CASE WHEN (Col2 IS NULL) OR (Col2 = '') THEN
REPLICATE(' ', COL_LENGTH('MyTable', 'Col2')/2)
ELSE Col2 + REPLICATE(' ', (COL_LENGTH('MyTable', 'Col2')/2)- LEN(Col2)) END),
Col3 = (SELECT CASE WHEN (Col3 IS NULL) OR (Col3 = '') THEN
REPLICATE(' ', COL_LENGTH('MyTable', 'Col1')/2)
ELSE Col3 + REPLICATE(' ', (COL_LENGTH('MyTable', 'Col3')/2)- LEN(Col3)) END),
Col4 = (SELECT CASE WHEN (Col4 IS NULL) OR (Col4 = '') THEN
REPLICATE(' ', COL_LENGTH('MyTable', 'Col4')/2)
ELSE Col4 + REPLICATE(' ', (COL_LENGTH('MyTable', 'Col4')/2)- LEN(Col4)) END);
Demo
I have a table in SQL Server that looks something like this:
What I need is this:
I tried playing around with Pivot a little bit, but of course that won't work because Pivot isn't trying to flip multiple instances of the same field, it's aggregating over multiple instance of the same field.
Does anyone have any ideas of how I can do this in T-SQL?
You can do this easily using dynamic PIVOT. This is full working example:
IF OBJECT_ID('[dbo].[DataSource]') IS NOT NULL
BEGIN;
DROP TABLE [dbo].[DataSource];
END;
CREATE TABLE [dbo].[DataSource]
(
[ID] SMALLINT
,[Value] CHAR(1)
);
INSERT INTO [dbo].[DataSource] ([ID], [Value])
VALUES (1, 'A')
,(1, 'B')
,(1, 'C')
,(2, 'A')
,(2, 'B')
,(3, 'C')
,(4, 'A')
,(4, 'B')
,(4, 'C');
DECLARE #MaxValue INT;
WITH DataSource AS
(
SELECT ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [Value]) AS [ValueID]
FROM [dbo].[DataSource]
)
SELECT #MaxValue = MAX([ValueID])
FROM DataSource;
DECLARE #DynamicSQLStatement NVARCHAR(MAX)
,#DynamicSQLPIVOTColumns NVARCHAR(MAX);
SELECT #DynamicSQLPIVOTColumns = STUFF
(
(
SELECT DISTINCT ',[Value' + CAST([number] AS VARCHAR(4)) + ']'
FROM master..[spt_values]
WHERE [number] BETWEEN 1 AND #MaxValue
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
SET #DynamicSQLStatement = N'
SELECT [ID], ' + #DynamicSQLPIVOTColumns + '
FROM
(
SELECT *
,''Value'' + CAST(ROW_NUMBER() OVER (PARTITION BY [ID] ORDER BY [Value]) AS VARCHAR(12)) AS [ColumnName]
FROM [dbo].[DataSource]
) DS
PIVOT
(
MAX([value]) FOR [ColumnName] IN (' + #DynamicSQLPIVOTColumns + ')
) PVT;';
EXEC sp_executesql #DynamicSQLStatement;
and the result is:
Something wrong? The value C for the ID = 3 is in the first column, not in the last. That's because I am not aware how you are defining which value is in which column and I am using ROW_NUMBER to create such mapping. I guess in your real data you have a way of doing this.
So, let's say you have additional table like this to define this ordering:
IF OBJECT_ID('[dbo].[DataSourceOrdering]') IS NOT NULL
BEGIN;
DROP TABLE [dbo].[DataSourceOrdering];
END;
CREATE TABLE [dbo].[DataSourceOrdering]
(
[OrderID] SMALLINT
,[Value] CHAR(1)
);
INSERT INTO [dbo].[DataSourceOrdering] ([OrderID], [Value])
VALUES (1, 'A')
,(2, 'B')
,(3, 'C');
Then instead using ROW_NUMBER to defined the ordering we are going to use this table:
DECLARE #MaxValue INT;
WITH DataSource AS
(
SELECT DSO.[OrderID]
FROM [dbo].[DataSource] DS
INNER JOIN [dbo].[DataSourceOrdering] DSO
ON DS.[Value] = DSO.[Value]
)
SELECT #MaxValue = MAX([OrderID])
FROM DataSource;
DECLARE #DynamicSQLStatement NVARCHAR(MAX)
,#DynamicSQLPIVOTColumns NVARCHAR(MAX);
SELECT #DynamicSQLPIVOTColumns = STUFF
(
(
SELECT DISTINCT ',[Value' + CAST([number] AS VARCHAR(4)) + ']'
FROM master..[spt_values]
WHERE [number] BETWEEN 1 AND #MaxValue
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1
,1
,''
);
SET #DynamicSQLStatement = N'
SELECT [ID], ' + #DynamicSQLPIVOTColumns + '
FROM
(
SELECT DS.*
,''Value'' + CAST(DSO.[OrderID] AS VARCHAR(12)) AS [ColumnName]
FROM [dbo].[DataSource] DS
INNER JOIN [dbo].[DataSourceOrdering] DSO
ON DS.[Value] = DSO.[Value]
) DS
PIVOT
(
MAX([value]) FOR [ColumnName] IN (' + #DynamicSQLPIVOTColumns + ')
) PVT;';
EXEC sp_executesql #DynamicSQLStatement;
Something like this?
WITH
t AS (
SELECT 1 AS ID, 'A' AS Value
UNION ALL SELECT 1, 'B'
UNION ALL SELECT 1, 'C'
UNION ALL SELECT 2, 'A'
UNION ALL SELECT 2, 'B'
UNION ALL SELECT 3, 'C'
UNION ALL SELECT 4, 'A'
UNION ALL SELECT 4, 'B'
UNION ALL SELECT 4, 'C'
)
SELECT ID,
MAX(CASE WHEN Value = 'A' THEN Value ELSE NULL END) AS Value1,
MAX(CASE WHEN Value = 'B' THEN Value ELSE NULL END) AS Value2,
MAX(CASE WHEN Value = 'C' THEN Value ELSE NULL END) AS Value3
FROM t
GROUP BY ID
I executed the below query and it executed well :-
SELECT table2id, stuff((select CHAR(13) + table1name from table1 where table1id=table2.table2id FOR XML PATH (''), TYPE
).value('.', 'varchar(max)')
, 1, 1, '')
from table2 where table2id=117 group by id;
But when I am using count(*) , like in below query :-
SELECT table2id, stuff((select CHAR(13) + count(*) from table1 where table1id=table2.table2id FOR XML PATH (''), TYPE
).value('.', 'varchar(max)')
, 1, 1, '')
from table2 where table2id=117 group by id;
I am getting the below error:
Msg 245, Level 16, State 1, Line 19
Conversion failed when converting the varchar value '
' to data type int.
Now how can I stuff all the columns in table1 ? could anyone help !
I want my result like below:-
table2id | table1name | table1id | table1color
------------------------------------------------------
117 | jon, jack | 117,117 | blue,red
( I am adding my sample data for table1 and table2) :-
table1:
table1id | table1name | table1color | table1city | table1animal |...(I
have 25 columns like this !)
--------------------------------------------------------------
117 | jon | blue | city1 | animal1
117 | jack | red | city2 | animal2
table2:
table2id | table2uniqueid
-------------------------
117 | asbn6383hhh3j3837
118 | kf9s8sujfu6df5d7j
This has nothing to do with stuff.
The reason you get the error is this:
count(*) returns an int. char(13) is a char. Whenever you try to do int + char SQL Server will try to implicitly convert the char to an int. Naturally, char(13) cannot be converted to an int.
What you need to to explicitly convert the count(*) to varchar:
SELECT table2id, stuff(
(
select CHAR(13) + cast(count(*) as varchar(10))
from table1
where table1id=table2.table2id
FOR XML PATH (''), TYPE).value('.', 'varchar(max)'), 1, 1, '')
from table2
where table2id=117
group by id;
Try this code it will helps you by using Dynamic Sql
Firstly i created Two physical Tables with sample data
CREATE TABLE Table1 (table1id INT , table1name Varchar(100) , table1color Varchar(100) , table1city Varchar(100) , table1animal Varchar(100))
INSERT INTO Table1
SELECT 117, 'jon' , 'blue' , 'city1' , 'animal1' UNION ALL
SELECT 117, 'jack', 'red' , 'city2' , 'animal2'
CREATE TABLE Table2( table2id INT, table2uniqueid nvarchar(1000))
INSERT INTO Table2
SELECT 117,'asbn6383hhh3j3837' Union all
SELECT 118,'kf9s8sujfu6df5d7j'
Dynamic Sql code to get the expected result
SET NOCOUNT ON
IF OBJECT_ID('Tempdb..#TEMP') IS NOT NULL
DROP TABLE #TEMP
CREATE TABLE #TEMP(ID INT IDENTITY ,Query nvarchar(max))
IF OBJECT_ID('Tempdb..#TEMP2') IS NOT NULL
DROP TABLE #TEMP2
CREATE TABLE #TEMP2(ID INT IDENTITY ,Query nvarchar(max))
DECLARE #MinID INT,
#MaxID INT,
#Sql nvarchar(max),
#Getcolumn nvarchar(max),
#Sql2 nvarchar(max),
#CteSql nvarchar(max),
#CteSql2 nvarchar(max),
#FullSql nvarchar(max)
DEClare #COlumn Table
(
ID INT IDENTITY,
COlumnname varchar(100)
)
INSERT into #COlumn(COlumnname)
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME='Table1'
SELECT #MinID=MIn(Id),#MaxID=MAX(ID)FRom #COlumn
While (#MinID <=#MaxID)
Begin
SELECT #Getcolumn=COlumnname From #COlumn WHERE ID=#MinID
SET #Sql=N' STUFF((SELECT '', ''+ CAST('+#Getcolumn +' AS VARCHAR(5))
FROM cte AS i
WHERE i.table1id=o.table1id For XML PATH ('''')),1,1,'''') AS '+#Getcolumn
INSERT INTO #TEMP(Query)
SELECT #Sql
SET #MinID=#MinID+1
END
SELECT DISTINCT #Sql2=
STUFF((SELECT ', '+ CAST(Query AS nvarchar(max)) FROM #TEMP i For Xml Path(''), type
).value('.', 'nvarchar(max)')
, 1, 2, '')
FROM #TEMP o
SET #Sql2=#Sql2 +' FRom Cte o'
SET #CteSql= 'SELECT Top 1 '+''' ;With cte
AS
(SELECT T2.table2id,''+ STUFF((SELECT '', ''+''T1.''+COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS
Where TABLE_NAME=''Table1'' For XML PATH ('''')),1,1,'''') +'' From Table2 T2
LEFT JOIN Table1 T1
On T1.table1id=t2.table2id )''' +'+CHAR(13)+CHAR(10)+'+'''SELECT DISTINCT table2id,''
FROM INFORMATION_SCHEMA.COLUMNS Where TABLE_NAME=''Table1'''
INSERT INTO #TEMP2(Query)
EXECUTE(#CteSql)
SELECT #CteSql2= Query From #TEMP2
SET #FullSql=#CteSql2+#Sql2
PRINT #FullSql
EXEC(#FullSql)
SET NOCOUNT OFF
Result After Running the Query
table2id table1id table1name table1color table1city table1animal
---------------------------------------------------------------------------------------
117 117, 117 jon, jack blue, red city1, city2 anima, anima
118 NULL NULL NULL NULL NULL
i want to create a query from multiple records as one record , but i don't want to use Pivot, is there any solutions?
here's the table :
ID Element_Name Value
1 Parmitha 100
2 Anggun 200
3 Chandra 300
4 BagusofTerror 400
and i want the result is like this :
paramitha , anggun, chandra , bagusofterror
100 , 200, 300, 400
You can use for xml path ('') to transpose the values of a column.
For example, you could write
select Element_Name + ', '
from TheTable
for xml path ('');
To get Parmitha, Anggun, Chandra, BagusofTerror,
Here's a live demo: http://www.sqlfiddle.com/#!3/71f88/24
You can also use COALESCE to pivot a results set of columns into a varchar variable:
CREATE TABLE #Pivot
(ID int, Element_Name varchar(50), Value int)
INSERT #Pivot values (1,'Parmitha',100)
INSERT #Pivot values (2,'Anggun',200)
INSERT #Pivot values (3,'Chandra',300)
INSERT #Pivot values (4,'BagusofTerror',400)
DECLARE #titles VARCHAR(1000)
DECLARE #values VARCHAR(1000)
SET #titles = ''
SET #values = ''
SELECT #titles = #titles + COALESCE(Element_Name + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #values = #values + COALESCE(convert(varchar, Value) + ',' , '')
FROM #Pivot ORDER BY ID
SELECT #titles
UNION ALL
SELECT #values
Gives:
Parmitha,Anggun,Chandra,BagusofTerror,
100,200,300,400,
Try this :-
Select
MAX(CASE WHEN colID = 1 THEN value ELSE NULL END) AS [Parmitha],
MAX(CASE WHEN colID = 2 THEN value ELSE NULL END) AS [Anggun],
MAX(CASE WHEN colID = 3 THEN value ELSE NULL END) AS [Chandra],
MAX(CASE WHEN colID = 4 THEN value ELSE NULL END) AS [BagusofTerror]
FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY ID) AS colID,
ID,
Element_Name,
value
FROM Sample
) AS d
SQL DEMO
Taking Wolf's answer into consideration ,using dynamic query and xml path
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX)
select #cols = STUFF((SELECT distinct ','
+ convert(varchar(max), Element_Name, 120)
from Sample
FOR XML PATH(''), TYPE
).value('.', 'varchar(MAX)')
,1,1,'')
set #query = 'SELECT' + #cols + ' from
(
select value, Element_Name
from Sample
) x
pivot
(
max(value)
for Element_Name in (' + #cols + ')
) p '
execute(#query);
Demo
By the way y don't u use PIVOT .Using PIVOT the same result can be achieved
Select [Parmitha],[Anggun],[Chandra],[BagusofTerror]
FROM
(
Select value,element_name from Sample
)src
pivot
(
max(value)
for Element_Name in ([Parmitha],[Anggun],[Chandra],[BagusofTerror])
)pvt
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