0

如何加入(内部)具有动态列的两个数据表 dt1 和 dt2。在动态 sql 中使用存储过程。

dt1 包含

emp id empname SickLeave  Casualleave
 1      h        1

dt2 包含

empid empname SickLeave Casualleave
1       h       5         5

我必须显示输出

empid empname SickLeave Casualleave
1       h      1/5         0/5

请指导我

谢谢

4

4 回答 4

1

您可以这样做STUFF()

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;

输出:

| EMPID | EMPNAME | SICKLEAVE | CASUALLEAVE |
---------------------------------------------
|     1 |       h |     1 / 5 |       0 / 5 |

看到这个 SQLFiddle

于 2013-08-06T10:52:38.303 回答
0

您不需要动态 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
于 2013-08-06T10:57:15.617 回答
0

所以也许这会做你想要的。sys.columns该查询从命名'%leave%'为表的地方获取所有列名,dt1或者dt2构建一个动态查询,然后执行该查询。它依赖于 sys.columns 和 sys.tables (这可能是坏的)并且具有源表名称dt1dt2硬编码。

在我看来,这不是一个好的解决方案,问题的正确解决方案可能是改变数据模型,使其leave成为它自己的实体。

我在EXECUTE最后注释掉了 in 并留下了PRINTin 这样你就可以在执行它之前看到查询会做什么。

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)

对我来说,这给出了以下输出(表结构略有改变,其中包含更多leave列):

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
于 2013-08-06T11:02:13.917 回答
0
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];

小提琴

于 2013-08-06T11:02:22.033 回答