TSQL Pivot没有聚合函数

ctr*_*yan 121 sql t-sql sql-server pivot pivot-without-aggregate

我有一张这样的桌子......

CustomerID   DBColumnName   Data
--------------------------------------
1            FirstName      Joe
1            MiddleName     S
1            LastName       Smith
1            Date           12/12/2009
2            FirstName      Sam
2            MiddleName     S
2            LastName       Freddrick
2            Date           1/12/2009
3            FirstName      Jaime
3            MiddleName     S
3            LastName       Carol
3            Date           12/1/2009
Run Code Online (Sandbox Code Playgroud)

我想要这个......

这可能使用PIVOT吗?

CustomerID  FirstName   MiddleName          LastName        Date
----------------------------------------------------------------------
1           Joe             S               Smith           12/12/2009
2           Sam             S               Freddrick       1/12/2009
3           Jaime           S               Carol           12/1/2009
Run Code Online (Sandbox Code Playgroud)

Cha*_*ana 157

是的,但是为什么 !!??

   Select CustomerID,
     Min(Case DBColumnName When 'FirstName' Then Data End) FirstName,
     Min(Case DBColumnName When 'MiddleName' Then Data End) MiddleName,
     Min(Case DBColumnName When 'LastName' Then Data End) LastName,
     Min(Case DBColumnName When 'Date' Then Data End) Date
   From table
   Group By CustomerId
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的选择.我在查询中使用了"Pivot",然后我切换到了这个并查看了两者一起运行的执行计划.这种方法成本为8%,Pivot方法占92%! (4认同)
  • 真的很喜欢这个解决方案,它还确保列包含正确的数据,而不是Pivot,谢谢! (3认同)
  • ^^这对我有用。PIVOT对于非数字值无效。 (2认同)
  • @CharlesBretana,您太棒了!你救了我的灵魂!)那是最好的解决方案。谢谢! (2认同)
  • 这部作品很棒!但是我如何防止 - `警告:空值被聚合或其他 SET 操作消除` (2认同)

gbn*_*gbn 89

你可以使用MAX聚合,它仍然可以工作.一个值的MAX =该值..

在这种情况下,您还可以在customerid上自行加入5次,按每个表引用按dbColumnName进行过滤.它可能会更好.

  • @Could你可以提供一些代码吗? (5认同)
  • 以一些代码/模拟为例将非常棒,并且可以完美地完成此答案。 (4认同)

mr_*_*air 16

WITH pivot_data AS
(
SELECT customerid, -- Grouping Column
dbcolumnname, -- Spreading Column
data -- Aggregate Column
FROM pivot2 
)
SELECT customerid, [firstname], [middlename], [lastname]
FROM pivot_data
PIVOT (max(data) FOR dbcolumnname IN ([firstname],[middlename],[lastname])) AS p;
Run Code Online (Sandbox Code Playgroud)

  • 这应该是可接受的答案,因为它显示了TSQL Pivot命令的正确使用。 (3认同)
  • 值得注意的是,在此查询中,“pivot2”是原始数据所在的表的名称。另外,这里使用 CTE 是多余的 - CTE 下面的“SELECT”语句可以只指定原始表的名称。 (2认同)
  • 值得注意的是,PIVOT会自动根据PIVOT本身未使用的列进行分组。因此,在此示例中,[data]和[dbcolumnname]位于PIVOT中,因此所有内容都将按[CustomerId]分组 (2认同)

ctr*_*yan 9

好的,抱歉这个糟糕的问题.gbn让我走上正轨.这就是我在答案中寻找的东西.

SELECT [FirstName], [MiddleName], [LastName], [Date] 
FROM #temp 
PIVOT
(   MIN([Data]) 
    FOR [DBColumnName] IN ([FirstName], [MiddleName], [LastName], [Date]) 
)AS p
Run Code Online (Sandbox Code Playgroud)

然后我不得不使用while语句并将上述语句构建为varchar并使用dynmaic sql.

使用这样的东西

SET @fullsql = @fullsql + 'SELECT ' + REPLACE(REPLACE(@fulltext,'(',''),')','')
SET @fullsql = @fullsql + 'FROM #temp '
SET @fullsql = @fullsql + 'PIVOT'
SET @fullsql = @fullsql + '('
SET @fullsql = @fullsql + ' MIN([Data])'
SET @fullsql = @fullsql + ' FOR [DBColumnName] IN '+@fulltext
SET @fullsql = @fullsql + ')'
SET @fullsql = @fullsql + 'AS p'

EXEC (@fullsql)
Run Code Online (Sandbox Code Playgroud)

使用while循环构建@fulltext并从表中选择不同的列名.谢谢你的回答.


sha*_*esh 8

SELECT
main.CustomerID,
f.Data AS FirstName,
m.Data AS MiddleName,
l.Data AS LastName,
d.Data AS Date
FROM table main
INNER JOIN table f on f.CustomerID = main.CustomerID
INNER JOIN table m on m.CustomerID = main.CustomerID
INNER JOIN table l on l.CustomerID = main.CustomerID
INNER JOIN table d on d.CustomerID = main.CustomerID
WHERE f.DBColumnName = 'FirstName' 
AND m.DBColumnName = 'MiddleName' 
AND l.DBColumnName = 'LastName' 
AND d.DBColumnName = 'Date' 
Run Code Online (Sandbox Code Playgroud)

编辑:我在没有编辑器的情况下编写了这个并且没有运行SQL.我希望,你明白了.


bie*_*ski 6

OP实际上并不需要在没有聚合的情况下进行转动,但对于那些来到这里的人来说,知道如何看待:

sql参数化cte查询

该问题的答案涉及需要没有聚合的数据透视的情况,因此这样做的一个例子是解决方案的一部分.