【问题标题】:Convert MS Access TRANSFORM/PIVOT query to SQL Server将 MS Access TRANSFORM/PIVOT 查询转换为 SQL Server
【发布时间】:2018-12-21 17:54:06
【问题描述】:

我需要将访问查询转换为 sql server 查询,但出现错误,有人可以指出错误原因吗?

这是 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 Server 中执行查询时得到的结果:

(受影响的 1 行)

消息 8114,级别 16,状态 1,行 17 转换数据类型时出错 nvarchar 到 int。

消息 473,级别 16,状态 1,第 17 行不正确的值“0.000642857” 在 PIVOT 运算符中提供。

消息 207,级别 16,状态 1,第 1 行无效的列名称 'Total Of X Avg 子组'。

【问题讨论】:

  • 在执行之前尝试打印你的动态 sql 字符串。无论如何都应该这样做,这样你才能真正知道你在运行什么。

标签: sql-server ms-access pivot


【解决方案1】:

我有这样通用的旋转存储过程

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'

【讨论】:

  • 谢谢你这对我有用...更改了 DROP TABLE IF EXISTS ##pivoting 因为我使用的是旧的 SQL Server 版本...
猜你喜欢
  • 2012-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多