sql将动态行转换为列

时间:2013-08-03 15:30:20

标签: sql sql-server sql-server-2008 tsql

主题:问题及其任务。 环境:SQL Server 2008或更高版本 数据库表:问题,任务和IssuesTasks

假设我有一个输入屏幕可以处理单个问题及其相关任务。

我们正在处理问题1,并列出了7个任务来检查。

用户检查7个任务中的3个已完成并保存到数据库。

是否可以编写一个SQL,在同一行显示带有7个任务的Issue1? (请记住,只检查了3个,因此其他的应为空)。

另请注意,IssuesTasks连接表中只有3个任务代表用户检查的内容。

3 个答案:

答案 0 :(得分:0)

PIVOT函数中使用SQL Server构建:

SELECT <non-pivoted column>,
    [first pivoted column] AS <column name>,
    [second pivoted column] AS <column name>,
    ...
    [last pivoted column] AS <column name>
FROM
    (<SELECT query that produces the data>)
    AS <alias for the source query>
PIVOT
(
    <aggregation function>(<column being aggregated>)
FOR
[<column that contains the values that will become column headers>]
    IN ( [first pivoted column], [second pivoted column],
    ... [last pivoted column])
) AS <alias for the pivot table>
<optional ORDER BY clause>;

您可以使用PIVOT和UNPIVOT关系运算符将表值表达式更改为另一个表。 PIVOT通过将表达式中一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在最终输出中需要的任何剩余列值上执行聚合。 UNPIVOT通过将表值表达式的列旋转到列值来执行与PIVOT相反的操作。

简单的AdventureWorks示例:

-- Pivot table with one row and five columns
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, 
[0], [1], [2], [3], [4]
FROM
(SELECT DaysToManufacture, StandardCost 
    FROM Production.Product) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])
) AS PivotTable;

更复杂的例子:

USE AdventureWorks2008R2;
GO
SELECT VendorID, [250] AS Emp1, [251] AS Emp2, [256] AS Emp3, [257] AS Emp4, [260] AS Emp5
FROM 
(SELECT PurchaseOrderID, EmployeeID, VendorID
FROM Purchasing.PurchaseOrderHeader) p
PIVOT
(
COUNT (PurchaseOrderID)
FOR EmployeeID IN
( [250], [251], [256], [257], [260] )
) AS pvt
ORDER BY pvt.VendorID;

For more information see here

答案 1 :(得分:0)

虽然您没有为表格提供架构,但要写出确切的查询并不容易,但请看一下

select
    I.Id,
    I.Name,
    max(case when IT.TaskId = 1 then T.Name end) as Task1,
    max(case when IT.TaskId = 2 then T.Name end) as Task2,
    max(case when IT.TaskId = 3 then T.Name end) as Task3,
    max(case when IT.TaskId = 4 then T.Name end) as Task4,
    max(case when IT.TaskId = 5 then T.Name end) as Task5,
    max(case when IT.TaskId = 6 then T.Name end) as Task6,
    max(case when IT.TaskId = 7 then T.Name end) as Task7
from Issues as I
    left outer join IssuesTasks as IT on IT.IssueId = I.Id
    left outer join Tasks as T on T.Id = IT.TaskID
group by I.Id, I.Name;

请参阅SQL FIDDLE示例

答案 2 :(得分:0)

如果这不是犹太人,请原谅我;我仍然适应这里的规则(stackoverflow的长期读者,第一天发布)。我实际上只是在我的新博客上写了一篇关于此的文章,我真诚地认为这会有所帮助。基本上,您可以动态构建透视列值并将它们传递给动态构建的PIVOT查询,如下所示:

IF (OBJECT_ID('tempdb..#TEMP') is not null) DROP TABLE #TEMP
DECLARE @cols NVARCHAR(2000)
SELECT DISTINCT DATE
INTO #TEMP
FROM T_EMPLOYEE_PRODUCTIVITY

SELECT @cols = ISNULL(@cols + ',', '') + '[' + CONVERT(NVARCHAR, DATE) + ']'
FROM #TEMP
ORDER BY DATE
SELECT @cols
DECLARE @query NVARCHAR(4000)
SET @query = 'SELECT EMPLOYEE_NAME, ' + @cols +
'FROM
(
SELECT EMPLOYEE_NAME, DATE, UNITS
FROM T_EMPLOYEE_PRODUCTIVITY
) AS SourceTable
PIVOT
(
SUM(UNITS)
FOR DATE IN ('+ @cols + ')
) AS PivotTable
ORDER BY EMPLOYEE_NAME'
SELECT @query

EXECUTE(@query)

如果您需要有关样本数据的更详细说明,请在此处查看:http://thrillhouseblog.blogspot.com/2013/08/dynamic-pivot-query-in-tsql-microsoft.html

我希望这有帮助!