【问题标题】:Extracting a row and converting it into column headers提取一行并将其转换为列标题
【发布时间】:2021-08-29 19:24:12
【问题描述】:

我有一个由单独界面暂存的表,该文件的标题是以下行的一部分:

ID Col1 Col2 Col3 Col4 Coln
Amt1 Amt2 Amt3 Amt4 Date
10 8.00 6.00 8.00 8.50 01/02/2021
12 7.00 7.00 3.50 8.00 03/01/2021

这些列是由接口动态创建的,因此它们将从 Col1 到 Coln,然后暂存到此表中。所以主要目标是创建一个 rdl 报告,该报告将显示表中的所有记录,每次界面运行时都会更改。

我无法修改界面,所以有没有办法可以将表中的整行标题提取到另一个表中,以使这些值成为列标题和值如下:

ID Amt1 Amt2 Amt3 Amt4 Date
10 8.00 6.00 8.00 8.50 01/02/2021
12 7.00 7.00 3.50 8.00 03/01/2021

或者有没有办法在 rdl 文件中正确显示这些数据并动态创建标题?

【问题讨论】:

  • 你如何定义哪一行是标题(记住表格没有内在的顺序)
  • 从表中选择,我已按其中一列排序,以便标题成为第一个/顶部记录
  • 确定哪一栏?请具体说明,否则我们无能为力
  • 看来真正的问题是你的导入过程,你应该解决这个问题。在导入过程中你应该定义你的第一行是标题行,然后你可以使用强类型列。
  • @Charlieface 在实际场景中,我想要的记录的ID是空白的。因此,如果我按 Col1 进行排序,则最高记录将是带有标题的记录。 Larnu 我目前无法更改导入,因此我正在寻找替代解决方案。

标签: sql-server reporting-services


【解决方案1】:

我必须说,这使用报告工具要容易得多,但如果您愿意,也可以使用动态 SQL 来完成。

最大的问题是您甚至不知道您有多少个基列,也不知道它们的名称是什么,因此我们需要执行两个动态查询:一次获取列为基列命名值,然后再次获取实际值。

动态 SQL 可能会让人非常困惑,请尽量清楚哪些部分是静态的,哪些是动态的。确保始终将 QUOTENAME(someValue) 用于动态列名,将 QUOTENAME(someValue , '''') 用于动态文本,这样可以确保它们被正确转义。

我假设带有ID IS NULL 的行是带有列名的行

DECLARE @sql nvarchar(max), @cols nvarchar(max);

SET @sql = N'
SELECT @cols = CONCAT_WS('','''
+ (
    SELECT '
,' + CASE WHEN c.name = 'ID' THEN '''ID''' ELSE
      'QUOTENAME(' + QUOTENAME(c.name) + ', '''') + ''='' + QUOTENAME(' + QUOTENAME(c.name, '''') + ')'
      END
    FROM sys.columns c
    WHERE c.object_id = OBJECT_ID('YourTable')
    FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)') + '
)
FROM YourTable t
WHERE ID IS NULL
';

PRINT @sql;  -- for testing

EXEC sp_executesql
  @sql,
  N'@cols nvarchar(max) OUTPUT',
  @cols = @cols OUTPUT;

SET @sql = N'
SELECT ' + @cols + '
FROM YourTable
WHERE ID IS NOT NULL
';

PRINT @sql; -- for testing

EXEC sp_executesql @sql;

db<>fiddle

【讨论】:

  • 您好,我使用的是 SSMS 2016,并且无法将 STRING_AGG 识别为内置函数。请问有什么替代方法?
  • 你必须使用FOR XML,已修改
【解决方案2】:

编写一个查询dynamically unpivots 表中的数据。

然后使用matrix report 动态旋转显示结果。

或者,如果返回的确切列数未知,但已知在某个最大可能列集合内,您可以生成包含所有可能列的报告,然后以编程方式设置列标题(或者如果所有可能的列标题也提前知道,静态创建),并以编程方式隐藏报表中没有数据的列。

【讨论】:

  • 感谢您的回答,但我认为在我得到正确的标题后这将起作用。目前表头是 col1, col2 ... 我希望表头是 amt1, amt2 ...。从那个表记录。如果我无缘无故地按原样处理表格,我仍然会得到 col1,col2 而不是我需要的实际标题。不知道这是否有意义
  • 但是在您上面的一个 cmets 中,您说“列数并不总是相同”。 “正常”的 SSRS 报告不能有可变数量的列。
  • 所以这意味着我的解决方案也可能不起作用。我真的不知道如何做到这一点,这就是我来这里的原因
  • 我给出的任何一种解决方案都可以。如果列不是“真正”动态的,则第二种方法更容易 - 即,存在最大可能的列数。第一种方法无论如何都有效,即使列完全不可预测,但实现起来要困难得多。
【解决方案3】:

由于标题行的 ID 为 NULL,因此您可以使用 FILTER 从表数据中过滤掉这条记录:

=IIF(ISNOTHING(Fields!ID.Value), 0 , 1)

然后对于您的标题行,您只需要为每列标识具有 NULL 值的记录。

=MAX(IIF(ISNOTHING(Fields!ID.Value), NOTHING, Fields!Col1.Value))

【讨论】:

    【解决方案4】:

    谢谢大家的回答,我最终整合了其中的大部分,但也将列数硬编码为 250,它不太可能达到这个数字,但它已作为临时解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多