繁体   English   中英

SQL Server-更好的解决方案,用于在2个表之间进行联接以将行旋转为列

[英]SQL Server - Better Solution for join between 2 tables pivoting rows into columns

大家好,我正在使用SQL Server 2016,我有一个名为support_event_log的表,如下所示:

|    event_nr  |    data     |  
|--------------|-------------|
|     1        |       x     |
|     2        |       x     |

还有一个名为support_event_log_params的表,如下所示:

|      event_nr   |   msg_param_nr |  msg_param_value |  
|-----------------|----------------|------------------|
|        1        |        1       |        x         |
|        2        |        1       |        x         |
|        2        |        2       |        y         |
|        2        |        3       |        z         |

我想通过列加入两个表Event_nr ,并转动柱msg_param_nr成根据与列的值数3分不同的列msg_param_value ,就像这样:

|      event_nr   | msg1 | msg2 | msg3 | data |  
|-----------------|------|------|------|   x  |
|        1        |  x   | null | null |   x  |
|        2        |  x   |  y   |   z  |   x  |

我首先尝试了以下查询:

SELECT A.event_nr 
      ,A.data
      ,CASE WHEN B.msg_param_nr = 1 THEN B.msg_param_value END AS msg1
      ,CASE WHEN B.msg_param_nr = 2 THEN B.msg_param_value END AS msg2
      ,CASE WHEN B.msg_param_nr = 3 THEN B.msg_param_value END AS msg3

FROM support_event_log A LEFT JOIN support_event_log_params B
  on A.event_nr=B.event_nr

但是我得到重复行的以下结果:

|      event_nr   | msg1 | msg2 | msg3 | data |  
|-----------------|------|------|------|   x  |
|        1        |  x   | null | null |   x  |
|        2        |  x   | null | null |   x  |
|        2        | null |  y   | null |   x  |
|        2        | null | null |   z  |   x  |

最后,经过一番思考,我得到了一个可行的解决方案,包含以下查询:

WITH col1 AS (
     SELECT A.event_nr, A.msg_param_value
     FROM support_event_log_params A
     WHERE A.msg_param_nr=1
 )
, col2 AS (
     SELECT A.event_nr, A.msg_param_value
     FROM support_event_log_params A
     WHERE A.msg_param_nr=2
 )
,col3 AS (
     SELECT A.event_nr, A.msg_param_value
     FROM support_event_log_params A
     WHERE A.msg_param_nr=3
 )
SELECT A.event_nr 
      ,A.data
      ,B.msg_param_value as msg1
      ,C.msg_param_value as msg2
      ,D.msg_param_value as msg3
FROM support_event_log A 
  LEFT JOIN col1 B on A.event_nr=B.event_nr
  LEFT JOIN col2 C on A.event_nr=C.event_nr
  LEFT JOIN col3 D on A.event_nr=D.event_nr

但是在同一张桌子上做3个withs似乎效率很低,有没有更好的解决方案? 我似乎找不到有效的方法

您只需要在第一个查询上聚合:

SELECT el.event_nr, el.data,
       MAX(CASE WHEN elp.msg_param_nr = 1 THEN elp.msg_param_value END) AS msg1,
       MAX(CASE WHEN elp.msg_param_nr = 2 THEN elp.msg_param_value END) AS msg2,
       MAX(CASE WHEN elp.msg_param_nr = 3 THEN elp.msg_param_value END) AS msg3
FROM support_event_log el LEFT JOIN
     support_event_log_params elp
     ON el.event_nr = elp.event_nr
GROUP BY el.event_nr, el.data;

请注意,我还将表别名更改为表名的缩写,而不是无意义的字母(例如AB

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM