如何在SQL select语句中动态创建列
发布时间:2021-03-06 07:08:15 所属栏目:MsSql教程 来源:网络整理
导读:我有3张桌子.团队,选项,OptionTeam. 团队拥有TeamId和Name Option包含OptionId,OptionGroup OptionTeam持有TeamId,OptionId,OptionGroup select a.TeamId,a.Name(select count(*) from OptionTeam ot where ot.TeamId=a.TeamId and ot.OptionGroup=4) as Opti
|
副标题[/!--empirenews.page--]
我有3张桌子.团队,选项,OptionTeam.
select a.TeamId,a.Name (select count(*) from OptionTeam ot where ot.TeamId=a.TeamId and ot.OptionGroup=4) as Option1,(select count(*) from OptionTeam ot where ot.TeamId=a.TeamId and ot.OptionGroup=5) as Option2,(select count(*) from OptionTeam ot where ot.TeamId=a.TeamId and ot.OptionGroup=6) as Option3,(select count(*) from OptionTeam ot where ot.TeamId=a.TeamId and ot.OptionGroup=11) as Option4 from Team a 我想获得一个团队列表,以及额外的列,表明每个团队有多少个选项连接到每个团队.这是通过上面的查询完成的,但我想用表Option中的OptionGroup替换4,5,6,11的值. 样本数据: Team TeamId 1 2 3 选项 OptionId | OptionGroup 11 | 4 12 | 5 13 | 4 14 | 4 15 | 5 OptionTeam TeamId | OptionId | OptionGroup 1 | 11 | 4 1 | 13 | 4 2 | 12 | 5 2 | 14 | 4 3 | 15 | 5 我想要的清单是 TeamId | Group4 (OptionGroup=4) | Group5 (OptionGroup=5) 1 | 2 | 0 2 | 1 | 1 3 | 0 | 1 解决方法你需要一个动态的支点才能做到这一点.这是存储过程:CREATE PROC [dbo].[pivotsp]
@query AS NVARCHAR(MAX),-- The query,can also be the name of a table/view.
@on_rows AS NVARCHAR(MAX),-- The columns that will be regular rows.
@on_cols AS NVARCHAR(MAX),-- The columns that are to be pivoted.
@agg_func AS NVARCHAR(257) = N'SUM',-- Aggregate function.
@agg_col AS NVARCHAR(MAX),-- Column to aggregate.
@output AS NVARCHAR(257) = N'',-- Table for results
@debug AS bit = 0 -- 1 for debugging
AS
-- Example usage:
-- exec pivotsp
-- 'select * from vsaleshistory',-- 'market,marketid,family,familyid,Forecaster,Forecasterid,product,productid',-- 'month',-- 'sum',-- 'ku',-- '##sales'
-- Input validation
IF @query IS NULL OR @on_rows IS NULL OR @on_cols IS NULL
OR @agg_func IS NULL OR @agg_col IS NULL
BEGIN
RAISERROR('Invalid input parameters.',16,1);
RETURN;
END
-- Additional input validation goes here (SQL Injection attempts,etc.)
BEGIN TRY
DECLARE
@sql AS NVARCHAR(MAX),@cols AS NVARCHAR(MAX),@newline AS NVARCHAR(2);
SET @newline = NCHAR(13) + NCHAR(10);
-- If input is a valid table or view
-- construct a SELECT statement against it
IF COALESCE(OBJECT_ID(@query,N'U'),OBJECT_ID(@query,N'V')) IS NOT NULL
SET @query = N'SELECT * FROM ' + @query;
-- Make the query a derived table
SET @query = N'(' + @query + N') AS Query';
-- Handle * input in @agg_col
IF @agg_col = N'*'
SET @agg_col = N'1';
-- Construct column list
SET @sql =
N'SET @result = ' + @newline +
N' STUFF(' + @newline +
N' (SELECT N'','' + quotename( '
+ 'CAST(pivot_col AS sysname)' +
+ ') AS [text()]' + @newline +
N' FROM (SELECT DISTINCT('
+ @on_cols + N') AS pivot_col' + @newline +
N' FROM' + @query + N') AS DistinctCols' + @newline +
N' ORDER BY pivot_col' + @newline +
N' FOR XML PATH(''''))' + @newline +
N',1,N'''');'
IF @debug = 1
PRINT @sql
EXEC sp_executesql
@stmt = @sql,@params = N'@result AS NVARCHAR(MAX) OUTPUT',@result = @cols OUTPUT;
IF @debug = 1
PRINT @cols
-- Create the PIVOT query
IF @output = N''
begin
SET @sql =
N'SELECT *' + @newline +
N'FROM (SELECT '
+ @on_rows
+ N',' + @on_cols + N' AS pivot_col'
+ N',' + @agg_col + N' AS agg_col' + @newline +
N' FROM ' + @query + N')' +
+ N' AS PivotInput' + @newline +
N' PIVOT(' + @agg_func + N'(agg_col)' + @newline +
N' FOR pivot_col IN(' + @cols + N')) AS PivotOutput;'
end
ELSE
begin
set @sql = 'IF EXISTS (SELECT * FROM tempdb.sys.objects WHERE ' +
'name = ''' + @output + ''' AND type = N''U'') DROP TABLE tempdb.' + @output
EXEC sp_executesql @sql;
SET @sql =
N'SELECT * INTO ' + @output + @newline +
N'FROM (SELECT '
+ @on_rows
+ N',' + @agg_col + N' AS agg_col' + @newline +
N' FROM ' + @query + N')' +
+ N' AS PivotInput' + @newline +
N' PIVOT(' + @agg_func + N'(agg_col)' + @newline +
N' FOR pivot_col IN(' + @cols + N')) AS PivotOutput;'
end
IF @debug = 1
PRINT @sql
EXEC sp_executesql @sql;
END TRY
BEGIN CATCH
DECLARE
@error_message AS NVARCHAR(2047),@error_severity AS INT,@error_state AS INT;
SET @error_message = ERROR_MESSAGE();
SET @error_severity = ERROR_SEVERITY();
SET @error_state = ERROR_STATE();
RAISERROR(@error_message,@error_severity,@error_state);
RETURN;
END CATCH
(编辑:清远站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐
热点阅读

