sql - 透视重复的列名称并获取列的所有值

标签 sql sql-server sql-server-2008 tsql pivot

说明

假设我有 2 张 table 。 FormFields 其中将列名称存储为值,应进行透视,第二个表 FilledValues 包含用户通过提供的 FormFieldId 填充的值。

问题

正如您在 FormFields 表中看到的(下面的示例部分),我有重复的名称,但 ID 不同。我需要在连接表后,FilledValues 表中的所有值都将分配给列名,而不是 Id。

我需要更好的内容,您将在下面的输出部分中看到。

样本数据

表单字段

ID   Name  GroupId
1    col1     1
2    col2     1
3    col3     1
4    col1     2
5    col2     2
6    col3     2

填充值

ID  Name  FormFieldId  GroupID
1     a       2           1
2     b       3           1
3     c       1           1
4     d       4           2
5     e       6           2
6     f       5           2

现在输出

col1    col2    col3
 c       a        b  -- As you see It returning only values for FormFieldId 1 2 3
                     -- d, e, f are lost that because It have duplicate col names, but different id's

期望输出

col1    col2    col3
 c       a        b
 e       f        d 

查询

SELECT * FROM 
(
    SELECT  FF.Name  AS NamePiv, 
            FV.Name  AS Val1     
    FROM FormFields FF
    JOIN FilledValues FV ON FF.Id = FV.FormFieldId      
) x
PIVOT
(
    MIN(Val1)
    FOR NamePiv IN ([col1],[col2],[col3])
) piv

<强> SQL FIDDLE

如何生成多行输出?

最佳答案

由于您使用的是 PIVOT,因此数据正在被聚合,因此您只为分组的每一列返回一个值。您的子查询中没有任何唯一的列,并且在 PIVOT 的分组方面使用它来返回多行。为了做到这一点,你需要一些值(value)。如果每个“组”都有一个具有唯一值的列,那么您可以使用该列,或者可以使用像 row_number() 这样的窗口函数。

row_number() 将为每个 FF.Name 创建一个序列号,这意味着如果您有 2 个 col1,您将生成一个 1 表示一行,2 表示另一行。一旦将其包含在子查询中,您现在就有了一个在聚合数据时使用的唯一值,并且您将返回多行:

SELECT [col1],[col2],[col3]
FROM 
(
  SELECT 
    FF.Name  AS NamePiv, 
    FV.Name  AS Val1,   
    rn = row_number() over(partition by ff.Name order by fv.Id)
  FROM FormFields FF
  JOIN FilledValues FV ON FF.Id = FV.FormFieldId        
) x
PIVOT
(
  MIN(Val1)
  FOR NamePiv IN ([col1],[col2],[col3])
) piv;

参见SQL Fiddle with Demo 。输出为:

| col1 | col2 | col3 |
|------|------|------|
|    c |    a |    b |
|    e |    f |    d |

关于sql - 透视重复的列名称并获取列的所有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31857386/

相关文章:

sql-server - 像 USE 这样的函数指向不同服务器上的 SQL 数据库?

mysql - LEFT JOIN 使用日期列的最新行

sql - 使用默认路径中的文件创建数据库

php - 记录对 SQL Server 数据库的更改并将其发送到客户端的最佳方式?

SQL 更新 - 更新选定的行

javascript - Node.js mssql 模块非常慢

mysql - 从其他两列计算 SQL 中的获胜百分比

sql - 选择所有子记录都具有特定状态的父记录

sql - 相关子查询出错。 "MultiPart ID oh.SalesOrderID could not be bound"

ms-access - "' PK_dbo.TableName ' is not a valid name"带有到 SQL Server 的 Access ODBC 链接表