SQL Server:在使用where子句的同时将2行值转换为1列并加入它

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SQL Server:在使用where子句的同时将2行值转换为1列并加入它相关的知识,希望对你有一定的参考价值。

我正在使用SQL Server数据库并具有以下表格

表“数据”

   ------------------
   | Id | data_name |
   ------------------
   | 1  |Data 1     |
   | 2  |Data 2     |
   | 3  |Data 3     |
   | 4  |Data 4     |
   | 5  |Data 5     |
   ------------------

和表“Value_data”

   --------------------------------------------------------------------------------------------------------------
   | Id | data_id   | date       | col_1_type | col_1_name | col_1_value | col_2_type | col_2_name | col_2_value |
   --------------------------------------------------------------------------------------------------------------
   | 1  | 1         | 2017-01-01 | A          | Alpha      | 12          | B          | Beta       | 23          |
   | 2  | 1         | 2017-02-01 | A          | Alpha      | 32          | B          | Beta       | 42          |
   ---------------------------------------------------------------------------------------------------------------

而且我想做出这样的结果

   -----------------------------------------------------------------
   |value_id | data_id | data_name | date       | A-Alpha | B-Beta |
   -----------------------------------------------------------------
   |1        | 1       | Data 1    | 2017-01-01 | 12      | 23     |
   |2        | 1       | Data 1    | 2017-02-01 | 32      | 42     |
   -----------------------------------------------------------------

我已经多次搜索解决方案,我尝试过使用Pivot,但它不能很好地处理我在连接表中使用的数据,任何人都有相同案例的解决方案吗?

答案

这看起来像一个基本的左连接

create table data( Id int, data_name varchar(20))
insert into data values
( 1  ,'Data 1'),     
( 2  ,'Data 2'),     
( 3  ,'Data 3'),     
( 4  ,'Data 4'),     
( 5  ,'Data 5')     

create table Value_data( Id int,  data_id   int, dt  smalldatetime, col_1_type varchar(1), col_1_name varchar(5), col_1_value int, col_2_type varchar(1), col_2_name varchar(5), col_2_value int)
insert into value_data values
( 1  , 1         , '2017-01-01' , 'A'          , 'Alpha'      , 12          , 'B'          , 'Beta'       , 23          ),
( 2  , 1         , '2017-02-01' , 'A'          , 'Alpha'      , 32          , 'B'          , 'Beta'       , 42          )

select d.id,vd.id,d.data_name,vd.dt,
        vd.col_1_value as 'Alpha',vd.col_2_value as 'Beta'
from data d
left join value_data vd on d.id = vd.data_id

id          id          data_name            dt                      Alpha       Beta
----------- ----------- -------------------- ----------------------- ----------- -----------
1           1           Data 1               2017-01-01 00:00:00     12          23
1           2           Data 1               2017-02-01 00:00:00     32          42
2           NULL        Data 2               NULL                    NULL        NULL
3           NULL        Data 3               NULL                    NULL        NULL
4           NULL        Data 4               NULL                    NULL        NULL
5           NULL        Data 5               NULL                    NULL        NULL

(6 row(s) affected)
另一答案

你可以用它。

DECLARE @Data TABLE ( Id INT, data_name VARCHAR(10) )
INSERT INTO @Data VALUES
( 1 ,'Data 1'),
( 2 ,'Data 2'),
( 3 ,'Data 3'),
( 4 ,'Data 4'),
( 5 ,'Data 5')

DECLARE @Value_data TABLE (Id INT, data_id INT, [date] DATE, col_1_type VARCHAR(10), col_1_name VARCHAR(10), col_1_value INT, col_2_type VARCHAR(10), col_2_name VARCHAR(10), col_2_value INT)
INSERT INTO @Value_data VALUES
( 1, 1, '2017-01-01','A','Alpha','12','B','Beta','23'),
( 2, 1, '2017-02-01','A','Alpha','32','B','Beta','42')

;WITH CTE AS (
    select vd.Id value_id
        , vd.data_id 
        , d.data_name 
        , vd.[date]
        , vd.col_1_type + '-' +vd.col_1_name Col1
        , vd.col_1_value
        , vd.col_2_type + '-' +vd.col_2_name Col2
        , vd.col_2_value
    from @Value_data vd
        inner join @Data d on vd.data_id = d.Id
)   
SELECT * FROM CTE 
    PIVOT( MAX(col_1_value) FOR Col1 IN ([A-Alpha])) PVT_A
    PIVOT( MAX(col_2_value) FOR Col2 IN ([B-Beta])) PVT_B

结果:

value_id    data_id     data_name  date       A-Alpha     B-Beta
----------- ----------- ---------- ---------- ----------- -----------
1           1           Data 1     2017-01-01 12          23
2           1           Data 1     2017-02-01 32          42
另一答案
SELECT
  a.id,
  a.data_id,
  b.data_name,
  a.date1,
  a.col_1_value AS alpha,
  a.col_2_value AS beta
FROM table1 a WITH (NOLOCK)
INNER JOIN table2 b WITH (NOLOCK)
  ON a.data_id = b.id

enter image description here

以上是关于SQL Server:在使用where子句的同时将2行值转换为1列并加入它的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:如何将 UNION 与两个都有 WHERE 子句的查询一起使用?

在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数,将按照怎么样的顺序执行?

SQL Server:在包含连接的where子句中使用LEN或变量

如何强制 SQL Server 在 WHERE 子句之前处理 CONTAINS 子句?

将用户输入的搜索查询转换为用于 SQL Server 全文搜索的 where 子句

SQL Server:动态 where 子句