【问题标题】:Join Vertical & Horizontal table in SQL Server using Pivot使用 Pivot 连接 SQL Server 中的垂直和水平表
【发布时间】:2016-12-21 07:21:42
【问题描述】:

我想将两张表合并为一张,但问题是一张表是水平格式,另一张是垂直格式。

下面是表结构,join 将在 Employeeid 上:

表 1:EmpDetail

ID | CODE   | Name
-- |--------| ---
1  | 1008M  | ABC
2  | 1039E  | XYZ
3  | 1040E  | TYS

表 2:EmpCustomeDetail

EmpID | FiledName   | FieldValue 
--    |--------     |  ---
1     | FlD1        | temp1
1     | FlD2        | temp2
1     | FlD3        | temp3
2     | FlD1        | temp1
3     | FLD4        | temp6

所需的输出:

EmpID |  Code |  Name | Fld1  | Fld2  | Fld3  | Fld4 
--    |----   | ------|  ---  | ----  |----   |----  
1     | 1008M | ABC   | temp1 | temp2 | temp3 | null
2     | 1039E | XYZ   | temp1 | null  | null  | null
3     | 1040E | TYS   | null  | null  | null  | temp6

我曾尝试使用 Pivot Query,但它没有给出我要求的准确输出 以下是到目前为止我尝试过的查询

SELECT A.*
FROM (
    SELECT
        e.Id,
        e.code,
        e.Fname,        
    FROM EmpDetail e  
    LEFT JOIN (
        SELECT *
        FROM (
            SELECT
                  d.CustomeFieldName
                , c.ComboValue
                , d.EmployeeId              
            FROM EmpCustomeDetail d
        ) src 
        PIVOT (
            MAX(FieldValue)          
        ) src2
    ) c ON e.Id = c.EmployeeId       

) A

【问题讨论】:

  • 所有后面的列名(Fld1 到 FldX)都提前知道了吗?你知道他们的人数吗?

标签: sql sql-server sql-server-2008


【解决方案1】:

这里有两个说法:

第一个是简单的PIVOT。您可以使用它,以防您提前知道所有字段名(顺便说一句:您的示例中有错字)。

第二个语句大致相同,但列名是动态获取的。这将适用于(几乎)任何计数和不同的命名。

首先是一个模型-test-scenraio

CREATE TABLE DummyEmpDetail (ID INT,CODE VARCHAR(10),Name VARCHAR(100));
INSERT INTO DummyEmpDetail VALUES
 (1,'1008M','ABC')
,(2,'1039E','XYZ')
,(3,'1040E','TYS');

CREATE TABLE DummyEmpCustomeDetail (EmpID INT,FiledName VARCHAR(100),FieldValue VARCHAR(100)); 
INSERT INTO DummyEmpCustomeDetail VALUES
 (1,'FlD1','temp1')
,(1,'FlD2','temp2')
,(1,'FlD3','temp3')
,(2,'FlD1','temp1')
,(3,'FLD4','temp6');

--静态PIVOT语句

SELECT p.EmpID
      ,p.Name
      ,p.CODE
      ,p.Fld1
      ,p.Fld2
      ,p.Fld3
      p,Fld4
FROM
(
    SELECT e.CODE,e.Name,ec.*
    FROM DummyEmpDetail AS e
    INNER JOIN DummyEmpCustomeDetail AS ec ON e.ID=ec.EmpID
) AS tbl
PIVOT
(
    MAX(FieldValue) FOR FiledName IN(Fld1,Fld2,Fld3,Fld4)
) AS p;

--动态PIVOT语句

DECLARE @colNames VARCHAR(MAX)=
(
    STUFF
    (
        (
            SELECT DISTINCT ',' + QUOTENAME(FiledName) FROM DummyEmpCustomeDetail
            FOR XML PATH('')
        ),1,1,''
    )   
);
DECLARE @command VARCHAR(MAX)=
'SELECT p.EmpID
      ,p.Name
      ,p.CODE
      ,' + @colNames + 
' FROM
(
    SELECT e.CODE,e.Name,ec.*
    FROM DummyEmpDetail AS e
    INNER JOIN DummyEmpCustomeDetail AS ec ON e.ID=ec.EmpID
) AS tbl
PIVOT
(
    MAX(FieldValue) FOR FiledName IN(' + @colnames + ')
) AS p;';

EXEC (@command);
GO

DROP TABLE DummyEmpCustomeDetail;
DROP TABLE DummyEmpDetail;

两者都导致相同的结果...

【讨论】:

    【解决方案2】:

    尝试如下。如果fieldname 的值不是静态的,那么您应该使用dynamic sql

     SELECT EMPID,
               CODE,
               NAME,
               FLD1,
               FLD2,
               FLD3,
               FLD4
        FROM   EmpDetail C
               JOIN (SELECT A.*
                     FROM   EmpCustomeDetail
                            PIVOT ( MIN([FIELDVALUE])
                                  FOR [FILEDNAME] IN([FLD1],
                                                     [FLD3],
                                                     [FLD2],
                                                     FLD4) )A)B
                 ON C.ID = B.[EMPID] 
    

    【讨论】:

      【解决方案3】:

      不需要子查询。

      select  e.*,FlD1,FlD2,FlD3,FlD4 
      from    EmpDetail e
              left join EmpCustomeDetail 
                            pivot (max(FieldValue) for FiledName in (FlD1,FlD2,FlD3,FlD4)) ecd
              on ecd.EmpID = e.ID
      

      +----+-------+------+-------+-------+-------+-------+
      | ID | CODE  | Name | FlD1  | FlD2  | FlD3  | FlD4  |
      +----+-------+------+-------+-------+-------+-------+
      | 1  | 1008M | ABC  | temp1 | temp2 | temp3 | NULL  |
      +----+-------+------+-------+-------+-------+-------+
      | 2  | 1039E | XYZ  | temp1 | NULL  | NULL  | NULL  |
      +----+-------+------+-------+-------+-------+-------+
      | 3  | 1040E | TYS  | NULL  | NULL  | NULL  | temp6 |
      +----+-------+------+-------+-------+-------+-------+
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-19
        • 2013-08-09
        • 2020-02-25
        • 2012-03-04
        • 1970-01-01
        相关资源
        最近更新 更多