SQL 将 n 列转为单行
SQL Pivot With n Columns into Single Row
我有 XML 个文件,其中包含工程测试数据。任何给定的 XML 文件都有 n 个可能的参数定义,但参数定义是固定结构的。
<ParameterDef>
<ParameterDefId>1</ParameterDefId>
<Name>name</Name>
<Description>desc</Description>
<LowLimit>0.00E+00</LowLimit>
<HighLimit>1.00E+03</HighLimit>
<SpecLowLimit>-1.00E+32</SpecLowLimit>
<SpecHighLimit>1.00E+32</SpecHighLimit>
</ParameterDef>
我为参数定义创建了一个 table 并将我的 n 参数定义插入到 table.
ParameterDefId
Name
Description
LowLimit
HighLimit
SpecLowLimit
SpecHighLimit
1
Test_One
Test_One_Desc
0.00E+00
1.00E+03
-1.00E+32
1.00E+32
2
Test_Two
Test_Two_Desc
2.00E-15
2.00E-10
-1.00E+32
1.00E+32
出于某些原因,我需要将这些 n 参数定义拉到一行中。我知道理论上我可以为此使用 PIVOT,但我得到的所选值大多返回 NULL:
SELECT [1], [2], [3], [4], [5], [6], [7], [8]
FROM (
SELECT ParameterDefId, [Name], LowLimit, HighLimit, SpecLowLimit, SpecHighLimit
FROM dbo.ParameterDefinitions def
) dat
PIVOT(
MAX(LowLimit) -- Max(HighLimit), etc
FOR ParameterDefId IN ([1], [2], [3], [4], [5], [6], [7], [8])
)pvt
如果可能,我想在旋转时为我的列添加别名,以便每个列名称对于它所在的行都是唯一的:即 Test_One_LowLimit、Test_One_HighLimit 等。我似乎找不到以编程方式创建别名的方法。
我不是第一个需要这样东西的人,但我是 PIVOT 的新手,我不完全确定我知道我在做什么(这可能是显而易见的)。
我更愿意避免 d-sql,但我知道这可能是不可能的;但我仍然不确定如何在 d-sql.
中制定我需要的查询
明确地说,这就是我所追求的:
ParentTestData
Test_One_LowLimit
Test_One_HighLimit
etc
Test_Two_Lowlimit
Test_Two_HighLimit
something
0.00E+00
1.00E+03
etc
2.00E-15
2.00E-10
我可能对 PIVOT 的作用有错误的想法,但在那种情况下我仍然需要一种方法来实现这一点。
编辑 1:如果相关的话,它是 SQL 服务器 11。
编辑 2:
从一些评论中可以清楚地看出,我试图简明扼要,但我没有清楚地传达我在寻找什么。
我目前有两个 table。一个里面有测试数据。一个有那些测试的参数定义。给定测试的参数定义是可变数量的定义。我从中提取的参数定义 table 具有已定义的结构。
现在,当我从这两个 table 中提取数据以提供给不受我控制的外部软件时,我需要提供它 all 将给定测试的数据作为一行,无论给定测试在参数定义中有多少条目 table.
我不需要保留这个。我不需要把它存放在任何地方;存储发生在这部分过程甚至相关之前。我只需要知道如何从我拥有的 table 中提取数据并将其放入我需要的格式中。
如果有 PIVOT 的替代方案,或者这可以使用少量 CTE(甚至是游标作为最后的手段)来完成,我对此表示满意并愿意接受建议。
只要最终产品易于理解和易于维护,我并不特别关心它是如何完成的。我问的是 PIVOT,因为这是我对如何在 SQL 服务器中将行转换为列的理解。
我试图避免的是必须为每个产品创建一个 table 并测试客户拥有或发明的所有相关管道和维护。这将被写入一个 SPROC,所以一系列的查询得到最终结果就可以了。
如果我仍然对我想要完成的事情感到困惑,请让我知道如何更清楚地与您沟通我的最终目标是什么。谢谢。
您正在寻找的模板就是@charlieface 提到的模板...
SELECT
MAX(CASE WHEN ParameterDefId = 1 THEN [Name] END) AS Name_1,
MAX(CASE WHEN ParameterDefId = 1 THEN LowLimit END) AS LowLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN HighLimit END) AS HighLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN SpecLowLimit END) AS SpecLowLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN SpecHighLimit END) AS SpecHighLimit_1,
MAX(CASE WHEN ParameterDefId = 2 THEN [Name] END) AS Name_2,
MAX(CASE WHEN ParameterDefId = 2 THEN LowLimit END) AS LowLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN HighLimit END) AS HighLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN SpecLowLimit END) AS SpecLowLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN SpecHighLimit END) AS SpecHighLimit_2
FROM
yourTable
你需要动态 SQL 来实现它(写在 T-SQL 中或在数据库外部)。
查询数据以确定参数 ID 的数量(或列表,如果它们不是连续的),然后重复 MAX(CASE)
表达式 n 次。
我有 XML 个文件,其中包含工程测试数据。任何给定的 XML 文件都有 n 个可能的参数定义,但参数定义是固定结构的。
<ParameterDef>
<ParameterDefId>1</ParameterDefId>
<Name>name</Name>
<Description>desc</Description>
<LowLimit>0.00E+00</LowLimit>
<HighLimit>1.00E+03</HighLimit>
<SpecLowLimit>-1.00E+32</SpecLowLimit>
<SpecHighLimit>1.00E+32</SpecHighLimit>
</ParameterDef>
我为参数定义创建了一个 table 并将我的 n 参数定义插入到 table.
ParameterDefId | Name | Description | LowLimit | HighLimit | SpecLowLimit | SpecHighLimit |
---|---|---|---|---|---|---|
1 | Test_One | Test_One_Desc | 0.00E+00 | 1.00E+03 | -1.00E+32 | 1.00E+32 |
2 | Test_Two | Test_Two_Desc | 2.00E-15 | 2.00E-10 | -1.00E+32 | 1.00E+32 |
出于某些原因,我需要将这些 n 参数定义拉到一行中。我知道理论上我可以为此使用 PIVOT,但我得到的所选值大多返回 NULL:
SELECT [1], [2], [3], [4], [5], [6], [7], [8]
FROM (
SELECT ParameterDefId, [Name], LowLimit, HighLimit, SpecLowLimit, SpecHighLimit
FROM dbo.ParameterDefinitions def
) dat
PIVOT(
MAX(LowLimit) -- Max(HighLimit), etc
FOR ParameterDefId IN ([1], [2], [3], [4], [5], [6], [7], [8])
)pvt
如果可能,我想在旋转时为我的列添加别名,以便每个列名称对于它所在的行都是唯一的:即 Test_One_LowLimit、Test_One_HighLimit 等。我似乎找不到以编程方式创建别名的方法。
我不是第一个需要这样东西的人,但我是 PIVOT 的新手,我不完全确定我知道我在做什么(这可能是显而易见的)。
我更愿意避免 d-sql,但我知道这可能是不可能的;但我仍然不确定如何在 d-sql.
中制定我需要的查询明确地说,这就是我所追求的:
ParentTestData | Test_One_LowLimit | Test_One_HighLimit | etc | Test_Two_Lowlimit | Test_Two_HighLimit |
---|---|---|---|---|---|
something | 0.00E+00 | 1.00E+03 | etc | 2.00E-15 | 2.00E-10 |
我可能对 PIVOT 的作用有错误的想法,但在那种情况下我仍然需要一种方法来实现这一点。
编辑 1:如果相关的话,它是 SQL 服务器 11。
编辑 2: 从一些评论中可以清楚地看出,我试图简明扼要,但我没有清楚地传达我在寻找什么。
我目前有两个 table。一个里面有测试数据。一个有那些测试的参数定义。给定测试的参数定义是可变数量的定义。我从中提取的参数定义 table 具有已定义的结构。
现在,当我从这两个 table 中提取数据以提供给不受我控制的外部软件时,我需要提供它 all 将给定测试的数据作为一行,无论给定测试在参数定义中有多少条目 table.
我不需要保留这个。我不需要把它存放在任何地方;存储发生在这部分过程甚至相关之前。我只需要知道如何从我拥有的 table 中提取数据并将其放入我需要的格式中。
如果有 PIVOT 的替代方案,或者这可以使用少量 CTE(甚至是游标作为最后的手段)来完成,我对此表示满意并愿意接受建议。
只要最终产品易于理解和易于维护,我并不特别关心它是如何完成的。我问的是 PIVOT,因为这是我对如何在 SQL 服务器中将行转换为列的理解。
我试图避免的是必须为每个产品创建一个 table 并测试客户拥有或发明的所有相关管道和维护。这将被写入一个 SPROC,所以一系列的查询得到最终结果就可以了。
如果我仍然对我想要完成的事情感到困惑,请让我知道如何更清楚地与您沟通我的最终目标是什么。谢谢。
您正在寻找的模板就是@charlieface 提到的模板...
SELECT
MAX(CASE WHEN ParameterDefId = 1 THEN [Name] END) AS Name_1,
MAX(CASE WHEN ParameterDefId = 1 THEN LowLimit END) AS LowLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN HighLimit END) AS HighLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN SpecLowLimit END) AS SpecLowLimit_1,
MAX(CASE WHEN ParameterDefId = 1 THEN SpecHighLimit END) AS SpecHighLimit_1,
MAX(CASE WHEN ParameterDefId = 2 THEN [Name] END) AS Name_2,
MAX(CASE WHEN ParameterDefId = 2 THEN LowLimit END) AS LowLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN HighLimit END) AS HighLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN SpecLowLimit END) AS SpecLowLimit_2,
MAX(CASE WHEN ParameterDefId = 2 THEN SpecHighLimit END) AS SpecHighLimit_2
FROM
yourTable
你需要动态 SQL 来实现它(写在 T-SQL 中或在数据库外部)。
查询数据以确定参数 ID 的数量(或列表,如果它们不是连续的),然后重复 MAX(CASE)
表达式 n 次。