[英]Convert MS Access TRANSFORM/PIVOT query to SQL Server
我需要將訪問查詢轉換為 sql 服務器查詢,但出現錯誤,有人可以指出錯誤原因嗎?
這是 MS Access 查詢:
TRANSFORM Avg([X Avg Sub Group]) AS [AvgOfX Avg Sub Group]
SELECT Day, Process,
PARTNO_VAL0, CTQNO_VAL0,
ctq_description, MACHINE_VAL0,
usl, lsl,
Avg([X Avg Sub Group]) AS [Total Of X Avg Sub Group]
FROM [Capability Data with Shift]
WHERE (((Process)="BBB WELDING"))
GROUP BY Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl
PIVOT SHIFT_VAL0;
這是我所做的:
DECLARE @cols AS NVARCHAR(MAX);
DECLARE @query AS NVARCHAR(MAX);
SELECT @cols = STUFF((SELECT distinct ',' + QUOTENAME(avg([X Avg Sub Group]))
FROM [Capability Data with Shift]
WHERE (((Process)='BBB WELDING'))
GROUP BY Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl, SHIFT_VAL0
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
SET @query = ' SELECT Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl, [Total Of X Avg Sub Group], ' + @cols + '
FROM
(
SELECT Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0,
usl, lsl, SHIFT_VAL0, Avg([X Avg Sub Group]) AS [Total Of X Avg Sub Group]
FROM [Capability Data with Shift]
WHERE (((Process)=''BBB WELDING''))
GROUP BY Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl, SHIFT_VAL0
) t
PIVOT
(
avg([Total Of X Avg Sub Group])
FOR SHIFT_VAL0 IN( ' + @cols + ')
) p ';
Execute(@query);
這是我在 SQL 服務器中執行查詢時得到的結果:
(1 行受影響)
消息 8114,級別 16,State 1,第 17 行將數據類型 nvarchar 轉換為 int 時出錯。
消息 473,級別 16,State 1,第 17 行 PIVOT 運算符中提供了不正確的值“0.000642857”。
消息 207,級別 16,State 1,第 1 行無效的列名稱“X 平均子組的總數”。
不帶 cursor 的多用戶版本:
CREATE OR ALTER PROCEDURE [dbo].msrTransformAsAccessDo
@TRANSFORM_Function nvarchar(MAX),
@TRANSFORM_Field nvarchar(MAX),
@SQL_SELECT nvarchar(MAX),
@SQL_FROM_WHERE nvarchar(MAX),
@SQL_GROUPBY_HAVING_ORDERBY nvarchar(MAX),
@PIVOTBY nvarchar(MAX)
AS
BEGIN
SET NOCOUNT ON
DECLARE @Values nvarchar(MAX) = N''
DECLARE @tmpStr nvarchar(MAX)
DECLARE @RowCnt INT
DECLARE @id int = 1
DECLARE @DynSQL nvarchar(MAX) = N'INSERT INTO #pivoting SELECT DISTINCT ' + @PIVOTBY + ' as key_value ' + @SQL_FROM_WHERE + ' ORDER BY ' + @PIVOTBY
EXEC (@DynSQL)
SELECT @RowCnt = COUNT(*) FROM #pivoting;
--replace cursor
WHILE @id <= @RowCnt
BEGIN
SELECT @tmpStr = key_value from #pivoting where id = @id
SET @Values
= @Values + ', ' + @TRANSFORM_Function + '(Case When convert(nvarchar,' + @PIVOTBY
+ ')=convert(nvarchar,''' + @tmpStr + ''') Then ' + @TRANSFORM_Field + ' Else Null End) AS [' + @tmpStr
+ '] '
SET @id += 1
END
SET @DynSQL = @SQL_SELECT + ' ' + @Values + ' ' + @SQL_FROM_WHERE + ' ' + @SQL_GROUPBY_HAVING_ORDERBY
EXEC (@DynSQL)
END
在調用程序之前還需要創建臨時表(全局臨時不是 session 特定的):
BEGIN
--create temp table to ensure each user session has their own version of the pivot
CREATE TABLE #pivoting (id INT IDENTITY NOT NULL, key_value NVARCHAR(max))
EXECUTE [dbo].msrTransformAsAccessDo
'Avg',
'[X Avg Sub Group]',
'SELECT Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl, Avg([X Avg Sub Group]) AS [Total Of X Avg Sub Group] ',
'FROM [Capability Data with Shift] WHERE (((Process)=''BBB WELDING'')) ',
'GROUP BY Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl ',
'SHIFT_VAL0'
DROP TABLE #pivoting
END;
我有這樣的通用存儲過程可以進行數據透視
CREATE PROCEDURE [dbo].[msrTransformAsAccessDo]
@TRANSFORM_Function nvarchar(max),
@TRANSFORM_Field nvarchar(max),
@SQL_SELECT nvarchar(max),
@SQL_FROM_WHERE nvarchar(max),
@SQL_GROUPBY_HAVING_ORDERBY nvarchar(max),
@PIVOTBY nvarchar(max)
AS
BEGIN
SET NOCOUNT ON
DECLARE @DynSQL nvarchar(max)
SET @DynSQL = N' SELECT DISTINCT ' + @PIVOTBY + ' as key_value into ##pivoting ' + @SQL_FROM_WHERE + ' ORDER BY ' + @PIVOTBY
DROP TABLE IF EXISTS ##pivoting
EXEC (@DynSQL)
DECLARE @Values nvarchar(max) = N''
DECLARE @tmpStr nvarchar(max)
DECLARE @rsk CURSOR
SET @rsk = CURSOR SCROLL
FOR
select key_value from ##pivoting
OPEN @rsk
FETCH NEXT FROM @rsk INTO @tmpStr
WHILE @@FETCH_STATUS = 0
BEGIN
SET @Values = @Values + ', ' + @TRANSFORM_Function + '(Case When convert(nvarchar,' + @PIVOTBY + ')=convert(nvarchar,''' + @tmpStr + ''') Then ' + @TRANSFORM_Field + ' Else Null End) AS [' + @tmpStr + '] '
FETCH NEXT FROM @rsk INTO @tmpStr
END
CLOSE @rsk
DROP TABLE IF EXISTS ##pivoting
SET @DynSQL = @SQL_SELECT + ' ' + @Values + ' ' + @SQL_FROM_WHERE + ' ' + @SQL_GROUPBY_HAVING_ORDERBY
EXEC (@DynSQL)
END
GO
並呼吁您的情況:
EXECUTE msrTransformAsAccessDo
'Avg',
'[X Avg Sub Group]',
'SELECT Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl, Avg([X Avg Sub Group]) AS [Total Of X Avg Sub Group] ',
'FROM [Capability Data with Shift] WHERE (((Process)=''BBB WELDING'')) ',
'GROUP BY Day, Process, PARTNO_VAL0, CTQNO_VAL0, ctq_description, MACHINE_VAL0, usl, lsl ',
'SHIFT_VAL0'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.