主题:问题及其任务。环境:SQL Server 2008 以上数据库表:Issue、Tasks、IssueTasks
假设我有一个处理单个问题及其相关任务的输入屏幕。
我们正在处理问题 1,列出了 7 个要检查的任务。
用户将 7 个任务中的 3 个检查为已完成并保存到数据库。
是否可以编写一个 SQL 来显示 Issue1 与同一行上的 7 个任务?(请记住,只检查了 3 个,所以其他的应该为空)。
另请注意,IssueTasks 连接表中只有 3 个任务表示用户检查的内容。
主题:问题及其任务。环境:SQL Server 2008 以上数据库表:Issue、Tasks、IssueTasks
假设我有一个处理单个问题及其相关任务的输入屏幕。
我们正在处理问题 1,列出了 7 个要检查的任务。
用户将 7 个任务中的 3 个检查为已完成并保存到数据库。
是否可以编写一个 SQL 来显示 Issue1 与同一行上的 7 个任务?(请记住,只检查了 3 个,所以其他的应该为空)。
另请注意,IssueTasks 连接表中只有 3 个任务表示用户检查的内容。
使用 SQL server 内置PIVOT
函数:
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;
虽然您没有为您的表提供架构,但要编写准确的查询并不容易,但看看这个
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示例
如果这不符合犹太教规,请原谅;我仍然在适应这里的规则(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
我希望这有帮助!