Reputation: 73
How can I join (inner) the two datatable dt1 and dt2 that have dynamic coloumn. using stored procedure in dynamic sql.
dt1 contains
emp id empname SickLeave Casualleave
1 h 1
dt2 contains
empid empname SickLeave Casualleave
1 h 5 5
I have to show output like
empid empname SickLeave Casualleave
1 h 1/5 0/5
Please guide me
Thanks
Upvotes: 0
Views: 464
Reputation: 44881
So maybe this will do what you want. This query gets all the column names from sys.columns
named like '%leave%'
where the table is either dt1
or dt2
and builds a dynamic query that it then executes. It relies on the sys.columns and sys.tables (which might be bad) and has the source table names dt1
and dt2
hard coded.
In my opinion this is not a good solution, and the correct solution to the problem might be to alter the data model so that leave
becomes an entity of it's own.
I've commented out the EXECUTE
at the end and left the PRINT
in so you can see what the query will do before executing it.
DECLARE @Columns VARCHAR(MAX)
SELECT @Columns = COALESCE(@Columns + ',' + name + '', '' + name + '') FROM (
SELECT DISTINCT
'CAST(ISNULL(dt1.' + name + ',0) AS VARCHAR) + ''/'' + CAST(dt2.' + name + ' AS VARCHAR) AS ' + name + ' ' AS name
FROM sys.columns
WHERE NAME LIKE '%leave%'
AND object_id IN (SELECT object_id FROM sys.tables WHERE name IN ('dt1', 'dt2'))) LeaveColumns
DECLARE @SQL NVARCHAR(MAX)
SET @SQL = N'
SELECT
dt1.empid,
dt1.empname, ' + @Columns + '
FROM dt1
INNER JOIN dt2 ON dt1.empid=dt2.empid'
PRINT @SQL -- Uncomment to see the query which will be run
--EXECUTE(@SQL)
For me this gives the following output (with a slightly altered table structure where I included more leave
columns):
SELECT
dt1.empid,
dt1.empname,
CAST(ISNULL(dt1.casualleave,0) AS VARCHAR) + '/' + CAST(dt2.casualleave AS VARCHAR) AS casualleave ,
CAST(ISNULL(dt1.sickleave,0) AS VARCHAR) + '/' + CAST(dt2.sickleave AS VARCHAR) AS sickleave ,
CAST(ISNULL(dt1.someotherleave,0) AS VARCHAR) + '/' + CAST(dt2.someotherleave AS VARCHAR) AS someotherleave ,
CAST(ISNULL(dt1.yetanotherleave,0) AS VARCHAR) + '/' + CAST(dt2.yetanotherleave AS VARCHAR) AS yetanotherleave
FROM dt1
INNER JOIN dt2 ON dt1.empid=dt2.empid
Upvotes: 0
Reputation: 7123
select t1.[empid],t1.[empname],
Cast(COALESCE(t1.[SickLeave],0) as char)
+'/'
+cast(COALESCE(t2.[SickLeave],0) as char) as SickLeave,
Cast(COALESCE(t1.[Casualleave],0) as char)
+'/'
+cast(COALESCE(t2.[Casualleave],0) as char) as Casualleave
from Table1 t1 inner join Table2 t2 on
t1.[empid]=t2.[empid];
Upvotes: 0
Reputation: 17161
You don't need dynamic SQL...
SELECT emp_id
, empname
, dt1_sickleave + '/' + dt2_sickleave As sickleave
, dt1_casualleave + '/' + dt2_casualleave As casualleave
FROM (
SELECT Coalesce(dt1.emp_id, dt2.emp_id) As emp_id
, Coalesce(dt1.empname, dt2.empname) As empname
, Cast(Coalesce(dt1.sickleave , 0) As varchar(10)) As dt1_sickleave
, Cast(Coalesce(dt1.casualleave, 0) As varchar(10)) As dt1_casualleave
, Cast(Coalesce(dt2.sickleave , 0) As varchar(10)) As dt2_sickleave
, Cast(Coalesce(dt2.casualleave, 0) As varchar(10)) As dt2_casualleave
FROM dt1
FULL
JOIN dt2
ON dt2.emp_id = dt1.emp_id
) As x
Upvotes: 0
Reputation: 32602
You can do this using STUFF()
like this:
WITH CTE(empid, empname, SickLeave, Casualleave)
AS (SELECT * FROM dt1
UNION ALL
SELECT * FROM dt2
)
SELECT distinct empid, empname
, SickLeave =
STUFF((SELECT ' / ' + CONVERT(VARCHAR(20),[SickLeave])
FROM CTE b
WHERE b.empid = a.empid
FOR XML PATH('')), 1, 2, '')
, Casualleave =
STUFF((SELECT ' / ' + CONVERT(VARCHAR(20),[Casualleave])
FROM CTE C
WHERE C.empid = a.empid
FOR XML PATH('')), 1, 2, '')
FROM CTE a
GROUP BY Empid, empname;
Output:
| EMPID | EMPNAME | SICKLEAVE | CASUALLEAVE |
---------------------------------------------
| 1 | h | 1 / 5 | 0 / 5 |
Upvotes: 1