【问题标题】:Dynamically Pivot unknown Data动态透视未知数据
【发布时间】:2013-01-07 16:07:56
【问题描述】:

尝试在 C#/MVC4 中使用 LINQ 或 LAMBDA 对 动态 数据进行透视,并且几乎得出结论,这很难做到。..

这基本上是我想做的:

我已经能够使用此示例使其与已知列名一起使用:http://geekswithblogs.net/malisancube/archive/2009/04/21/using-lambda-or-linq-for-pivot-tables.aspx

但我找不到任何使用动态列执行此操作的示例。

通过动态列,我的意思是可能有一个具有不同名称和字段类型的新行,该行以前从未出现在表中,也需要转换为列。任何指针?

【问题讨论】:

  • 我也想知道是否可以创建一个 SQL 函数来为我解决这个问题。但我还没有找到使用 MVC4 中的 SQL 函数的好方法。即。我可以手动编写函数,但我更喜欢使用一些 MVC 风格的方法来调用函数。
  • 这必须在linq 中完成吗?这可以通过存储过程中的动态 SQL 轻松完成,具体取决于您的 RDBMS。
  • 我更愿意在 LINQ 中执行此操作,但如果没有其他选择,我愿意接受任何高效且快速的“好”解决方案。
  • 什么关系型数据库? sql server、oracle、mysql?什么版本?

标签: c# sql-server linq asp.net-mvc-4 lambda


【解决方案1】:

我不知道LINQ,所以我会给你一个可以在SQL Server 存储过程中使用的版本。这种类型的数据转换称为PIVOT。由于您使用的是 SQL Server 2008+,因此您可以使用该功能。

如果您知道要转换的值,则可以对这些值进行硬编码:

SELECT nodeid, rowid,[FirstName], [LastName], [Title]
FROM
(
    SELECT nodeid, rowid, name, value
    FROM yourTable
) x
PIVOT
(
   max(value)
   for name in ([FirstName], [LastName], [Title])
)p

SQL Fiddle with Demo

那么如果你有未知数量的值,你可以实现动态SQL:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(name) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT nodeid, rowid,' + @cols + ' from 
             (
                SELECT nodeid, rowid, name, value
                FROM yourTable
            ) x
            pivot 
            (
                max(value)
                for name in (' + @cols + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

两者都返回结果:

| NODEID | ROWID | FIRSTNAME | LASTNAME |  TITLE |
--------------------------------------------------
|      1 |     1 |    Alfred |   Beagle | (null) |
|      1 |     2 |    Freddy |   (null) | (null) |
|      1 |     3 |    (null) |     Grey |   Sir. |

【讨论】:

  • 很好的答案,我回家后会测试。想知道是否有什么特别需要考虑的关于 sql 注入的问题。值和名称列基本上可以包含任何内容。
  • 按照你的描述让它工作,试图看看我是否可以将它微调到一个单一的选择语句;)
  • @JensBerfenfeldt 很高兴你成功了。你可能可以,为了清楚起见,我把它分开了。 :)
  • 不知道怎么做,我想我可能不得不接受 2 个查询。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-25
  • 2014-10-16
相关资源
最近更新 更多