MSSQL / TSQL根据值将字段分隔成行

时间:2016-07-19 16:56:03

标签: sql sql-server tsql

我有两个表格,如:

表:test_results

ID  |test_id    |test_type  |result_1   |amps       |volts      |power      |
----+-----------+-----------+-----------+-----------+-----------+-----------+
1   |101        |static     |10.1       |5.9        |15         |59.1       |
2   |101        |dynamic    |300.5      |9.1        |10         |40.1       |
3   |101        |prime      |48.9       |8.2        |14         |49.2       |
4   |101        |dual       |235.2      |2.9        |11         |25.8       |
5   |101        |static     |11.9       |4.3        |9          |43.3       |
6   |101        |prime      |49.9       |5.8        |15         |51.6       |

table:test_records

ID  |model      |test_date  |operator   |
----+-----------+-----------+-----------+
101 |m-300      |some_date  |john doe   |
102 |m-243      |some_date  |john doe   |
103 |m-007      |some_date  |john doe   |
104 |m-523      |some_date  |john doe   |
105 |m-842      |some_date  |john doe   |
106 |m-252      |some_date  |john doe   |

我正在制作一份如下所示的报告:

                                               |static                                         |dynamic                                        |
test_id    |model      |test_date  |operator   |result_1   |amps       |volts      |power      |result_1   |amps       |volts      |power      |
-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+-----------+
101        |m-300      |some_date  |john doe   |10.1       |5.9        |15         |59.1       |300.5      |9.1        |10         |40.1       |

左外连接如下:

SELECT
    A.ID AS test_id, model, test_date, operator,
    B.result_1, B.amps, B.volts, B.power,
    C.result_1, C.amps, C.volts, C.power
FROM
    test_records A
LEFT JOIN
    test_results B
ON
    A.ID = B.test_id
    AND
    B.test_type = 'static'
LEFT JOIN
    test_results C
ON
    A.ID = C.test_id
    AND
    C.test_type = 'dynamic'

但我遇到了一个问题。 "静态"和"素数"测试运行两次。 我不知道如何区分它们以创建自己的4个字段。 所需报告的抽象(简化)视图如下所示:

|static     |dynamic    |prime      |dual       |static2    |prime2     |
|4 fields   |4 fields   |4 fields   |4 fields   |4 fields   |4 fields   |

这甚至可能吗? 注意:

  1. 我用html标记了4个字段的组,所以不要担心标签
  2. 并非所有测试都会运行"静态"和"素数"两次。所以这是一个If(" static"和" prime")被发现两次的情况,做这个SQL。
  3. 我认为我们要让我们的工程师在第二次测试中添加2,消除问题,所以这个问题更多是出于好奇而知道什么方法可以解决这样的问题。

1 个答案:

答案 0 :(得分:0)

如果您有另一个字段(此处我使用ID),您知道该字段将始终按字段排序,您可以使用窗口函数为它们提供顺序值,然后加入到该字段中。像这样:

WITH test_records_numbered AS
(  
   SELECT test_id, test_type, result_1, amps, volts, power, 
          ROW_NUMBER() OVER (PARTITION BY test_id, test_type ORDER BY ID) as type_num
   FROM test_records
)
SELECT
    A.ID AS test_id, model, test_date, operator,
    B.result_1, B.amps, B.volts, B.power,
    C.result_1, C.amps, C.volts, C.power
FROM test_records A
LEFT JOIN test_records_numbered B
      ON A.ID = B.test_id AND B.test_type = 'static' and B.type_num = 1
LEFT JOIN test_records_numbered C 
      ON A.ID = C.test_id AND C.test_type = 'dynamic' and C.type_num = 2

我使用CTE使其更清晰但你可以使用子查询,你当然必须在SQL中有两次相同的子查询,大多数服务器没有CTE我没有问题优化我期望的。

我觉得这个解决方案有点“黑客”。您确实希望原始数据具有所需的所有信息。所以我认为你的应用程序开发人员修改他们的代码(FWIW)是好的。

如果必须投入生产,我想我会打破编号,以便对可疑业务规则的编纂进行抄袭(并使其易于更改)