我有3张桌子:
payorderType :
---------
typeID | TypeName |
1 | accounting |
2 | budget |
----------
step:
----------
StepID | StepName | typeID
1 | payorder | 1
2 | cheque | 1
3 | cheque | 2
----------
user:
----------
userID | StepName | StepID
7878 | payorder | 1
4547 | cheque | 2
6538 | cheque | 1
----------
我想创建一个表,其中行和列中的用户包含step和payorderType的concat。同如下:
users | accounting_payorder | accounting_cheque | budget_cheque |
7878 | 1 | 0 | 0 |
4547 | 0 | 1 | 0 |
6538 | 0 | 1 | 0 |
我的问题是:如果我不知道payorderType行数和步行数,我该怎么写呢? 我的剧本在这里: 首先,我在游标中为concat payorderType创建一个表,然后执行步骤:
CREATE PROC sp_payOrderType
AS
BEGIN
DECLARE a CURSOR
FOR SELECT DISTINCT p.TypeName,s.StepName
FROM
dbo.PayOrderType p LEFT JOIN
dbo.vStep s ON s.TypeID = p.TypeID
FOR READ ONLY
DECLARE @payOrderType NVARCHAR(50),@stepName NVARCHAR(50)
DECLARE @SQL NVARCHAR(MAX)=''
OPEN a
FETCH NEXT FROM a INTO @payOrderType, @stepName
WHILE @@FETCH_STATUS=0
BEGIN
DECLARE @b VARCHAR(max), @b2 VARCHAR(max)
SELECT @b = ISNULL(@b ,'') +'['+ ISNULL(@payOrderType ,'')+ '____'+ISNULL(@stepName ,'')+ ']'+ ' NVARCHAR(1000) ,'
FETCH NEXT FROM a INTO @payOrderType,@stepName
END
CLOSE a
DEALLOCATE a
SELECT @SQL = 'ALTER table AA(' + SUBSTRING(@b,1, LEN(@b)-1) + ')'
SELECT @SQL
END
但我不知道我应该如何将行(userID)与列相关联?
答案 0 :(得分:0)
您应该已经确定了输出结构。具有可变输出结构的风险很小。
但是我们走了:
使您的结构简单(删除大部分变量) - 创建视图(或使用派生表)payorderType + step
-- should be inner join probably instead of left join
-- if you use left join you have to isnull s.StepName
SELECT
u.userID,
s.StepID,
p.TypeName,
s.StepName,
p.TypeName + '_' + s.StepName StepType,
-- Your column can be like `coalesce(p.TypeName + '_' + s.StepName, p.TypeName, s.StepName) StepType` for left joins
1 Point
FROM dbo.PayOrderType p
INNER JOIN dbo.vStep s ON s.TypeID = p.TypeID
INNER JOIN dbo.user u ON u.StepID = s.StepID
让您的查询更清晰(您的所有字段都可以包含空值吗?现在您只能处理一个列/变量。
现在是时间轴:
SELECT
userID,
[accounting_payorder],
[accounting_cheque],
[budget_cheque]
FROM newview v
PIVOT(MAX(point) FOR StepType in ([accounting_payorder], [accounting_cheque], [budget_cheque])
如果必要,您可以使用动态查询:
declare @header varchar(max),
@columns varchar(max)
select @header = coalesce(@header + ', ', '') + 'isnull(''' + StepType + ''', 0) ' + '[' + StepType + ']',
@columns = coalesce(@columns + ', ', '') + '[' + StepType + ']'
from newview
group by StepType
declare @sqlpvt varchar(4000) -- limited by lenght of exec statement
set @sqlpvt = 'select userID, $HEADER FROM newview v PIVOT(MAX(point) FOR StepType in ($COLUMNS)'
-- replace pseudovariables
set @sqlpvt = replace(@sqlpvt, '$HEADER', @header)
set @sqlpvt = replace(@sqlpvt, '$COLUMNS', @columns)
print @sqlpvt
exec (@sqlpvt)
对不起,如果有些想法是错误的(盲目写入),但我认为对于指南来说已经足够了。但是你应该更喜欢在第2步结束(非静态代码很危险)。