SQL选择一行,显示几行

时间:2014-10-15 13:29:43

标签: sql sql-server unpivot

我一直在寻找一个教程,但没有什么比我需要的更合适,所以我几乎猜测我想要的东西是不可能的。

我有一个表,其中包含一批产品的ID,后面跟着几个测试结果(即BatchNumber,Type,TestResultOne,TestResultTwo等......)。每批次共有30个测试。

我正在尝试创建一个select语句或一个显示批号的视图,测试列的ordinal_position(即TestResultOne为3)以及该结果的值。因此,当我在数据库中运行select语句时,我会收到一行,但是当我运行select / view时,我需要29行(对于产品上的每个测试都有一行)。

这可能吗?如果是这样的话:是否有一个教程向我展示如何做到这一点,如果没有,我怎么解决这个问题呢?

例如,我的表看起来像这样:

BatchID | Type | TestOne | TestTwo | TestThree | Test Four 
----------------------------------------------------------
00001   |  A   |   1.2   |   0     |  16       |   PASS
00002   |  A   |   1.3   |   1     |  15       |   FAIL

我希望得到:

BatchID | Test | Result
-----------------------
00001   |  2   |  1.2
00001   |  3   |  0
00001   |  4   | 16
00001   |  5   | PASS

2 个答案:

答案 0 :(得分:1)

看来你需要做的就是对你的桌子进行UNPIVOT。根据SQL Server的版本,可以使用UNPIVOT语句。我更喜欢UNIONing结果,而不是使用UNPIVOT语法。 以下内容适用于您。

DECLARE @TestResults TABLE (
    BatchID Int,
    TestType CHAR(1),
    TestOne SMALLMONEY,
    TestTwo SMALLMONEY,
    TestThree SMALLMONEY,
    TestFour SMALLMONEY
)
INSERT INTO @TestResults
SELECT 1, 'A', 1.2, 0, 16, 8.2 UNION
SELECT 2, 'A', 1.3, 1, 15, 7.4

SELECT BatchID, TestType, TestOne, TestTwo, TestThree, TestFour FROM @TestResults

这将返回您当前的结果。

BatchID     TestType TestOne     TestTwo     TestThree   TestFour
----------- -------- ----------- ----------- ----------- -----------
1           A        1.20        0.00        16.00       8.20
2           A        1.30        1.00        15.00       7.40

尝试使用以下查询来解决您的数据。

SELECT BatchID, 1 AS Test, TestOne AS Result FROM @TestResults UNION ALL
SELECT BatchID, 2 AS Test, TestTwo FROM @TestResults  UNION ALL
SELECT BatchID, 3 AS Test, TestThree FROM @TestResults  UNION ALL
SELECT BatchID, 4 AS Test, TestFour  FROM @TestResults 
ORDER BY BatchID, Test

这应该会返回所需的结果。

BatchID     Test        Result
----------- ----------- -----------
1           1           1.20
1           2           0.00
1           3           16.00
1           4           8.20
2           1           1.30
2           2           1.00
2           3           15.00
2           4           7.40

答案 1 :(得分:0)

尝试以下代码

DECLARE @query AS NVARCHAR(MAX)
DECLARE @cols AS NVARCHAR(MAX)

SET @cols = STUFF((select ','+quotename(C.name)
           FROM sys.columns c
           WHERE c.object_id = OBJECT_ID('Batches') 
           AND  c.name NOT IN ('BatchID', 'Type')
           for xml path('')), 1, 1, '')


SET @query =
  N'SELECT BatchID, Type, Col as Test, Val as Result
FROM
(
select BatchID, Type, ' + @cols + '
from Batches
) as cp
unpivot
(
Val for Col in (' + @cols + ')
) as up'

EXEC sp_executesql @query

为了首先解释代码,我们正在创建一个列表,您希望将其作为行,从而使用STUFF排除BatchIDType

SET @cols = STUFF((select ','+quotename(C.name)
           FROM sys.columns c
           WHERE c.object_id = OBJECT_ID('Batches') 
           AND  c.name NOT IN ('BatchID', 'Type')
           for xml path('')), 1, 1, '')

然后我们使用列名并使用表Batches上的列名执行UNPIVOT

SET @query =
  N'SELECT BatchID, Type, Col as Test, Val as Result
FROM
(
select BatchID, Type, ' + @cols + '
from Batches
) as cp
unpivot
(
Val for Col in (' + @cols + ')
) as up'

EXEC sp_executesql @query

SQL小提琴演示http://sqlfiddle.com/#!3/54977/6