我试图根据数据编写一个具有可变列数的查询,但我从未做过这样的事情。
我们正在运行ADO并希望有一个查询(可能带有子查询)但没有其他编码或GO语句,存储过程等。
我们计划在可编辑的网格中使用此查询的结果。
以下是我们的数据示例。我们有一份员工清单和一份项目清单。请注意,这不是"总结"交叉表。每个单元只有一个源编号。
我们希望查询结果为每个项目都有一列。此列中的单元格将包含该项目中该员工的小时数。
如果我们添加项目,我们希望在查询结果中显示另一列。
编辑:由于我们在代码中编写查询并提交它,我们可以动态生成查询。我们不需要动态生成代码。例如,在下面的数据中,我们将能够阅读(使用我们的母语)Project表,并知道我们有3个项目以及它们的名称。我们可以在阅读中看到的Pivot中使用它们,但只是不确定如何......
答案 0 :(得分:3)
这样的事情:http://sqlfiddle.com/#!6/2ded1/6
declare @pivotquery as nvarchar(max)
declare @columnname as nvarchar(max)
select @columnname= isnull(@columnname + ',','')
+ quotename(name)
from (select name from project) as t2
set @pivotquery =
N'with t1 as (
select ph.employee, e.name as empname, p.name, ph.hours
from project_hours ph
inner join project p
on p.id = ph.project
inner join employees e
on e.id = ph.employee
)
select *
from t1
pivot(sum(hours) for name in (' + @columnname + ')) as pivot_table'
exec sp_executesql @pivotquery
在此处提供了重要帮助和进一步说明:http://sqlhints.com/2014/03/18/dynamic-pivot-in-sql-server/
编辑:当我再次阅读您的问题时,我注意到您在代码中构建了查询,在这种情况下,您可能不需要上面的实用程序,但是您可以在其中构建{程序中的{1}}子句,如下所示:http://sqlfiddle.com/#!6/2ded1/12
for name in
答案 1 :(得分:1)
对于未来的读者,这里是一个使用两个嵌套派生表子查询的通用ANSI语法SQL查询。
此查询应该符合大多数RDMS(SQL Server,MySQL,SQLite,Oracle,PostgreSQL,DB2),因为它不使用CTE窗口函数(WITH
)或数据库特定的函数,如SQL Server' s Pivot()
:
SELECT [Key], [Employee Name], [Age],
Max(FF) As [First Floor],
Max(BSMT) As [Basement],
Max(PRKLotA) As [Parking Lot A]
FROM (
SELECT dT.Key,
dT.[Employee Name],
dT.[Age],
CASE WHEN dT.Project = 'First Floor' THEN dT.Hours END As FF,
CASE WHEN dT.Project = 'Basement' THEN dT.Hours END As BSMT,
CASE WHEN dT.Project = 'Parking Lot A' THEN dT.Hours END As PRKLotA
FROM (
SELECT [Employees].Key,
[Employees.[Employee Name],
Employees.Age, Projects.Project,
[Project Hours].Hours
FROM [Project Hours]
INNER JOIN Employees ON [Project Hours].[Employees FK] = Employees.Key
INNER JOIN Projects ON [Project Hours].[Projects FK] = Projects.Key
) AS dT
) As dT2
GROUP BY [Key], [Employee Name], [Age]
输出:
Key Employee Name Age First Floor Basement Parking Lot A
1 Tim 40 1000 3000
2 John 5 2000 4000 5000