动态SQL:按一个变量分组,为列名计算另一个变量

时间:2013-09-24 16:14:39

标签: sql sql-server dynamic

我正在尝试做一个动态的SQL查询,类似于在这个论坛上出现的一些,但对于我的生活,我无法让它工作。

我正在使用SQL Server 2008.我有一个包含一系列order_ref数字的表。这些数字中的每一个都具有与其相关联的不同数量的advice_ref。 advice_ref数字是唯一的(它们是另一个表中的键)。每个order_ref至少有一个advice_ref。有很多列描述了每个advice_ref的信息。

我想要做的是为每个唯一的order_ref创建一个表,每个advice_ref的列按升序排列。列将是Advice01,Advice02,.... Advice10,Advice11等。并非所有建议#列都将填入每个order_ref,建议#列的数量将取决于具有最大advice_refs数量的order_ref。

表格如下:

Order Advice01  Advice02  Advice03  Advice04.....
  1       1         2         3        
  2       5         8         9        20
  3       25

我尝试使用的代码是:

    DECLARE @SQL NVARCHAR(MAX)
    DECLARE @PVT NVARCHAR(MAX)

    SELECT  @SQL = @SQL + ', COALESCE(' + QUOTENAME('Advice' + RowNum) + ', '''') AS ' +  QUOTENAME('Advice' + RowNum),
            @PVT = @PVT + ', ' + QUOTENAME('Advice' + RowNum)
    FROM    (SELECT case when RowNum2 < 10 then '0'+RowNum2 when RowNum2 >=10 then RowNum2 end [RowNum] From
    (   SELECT  DISTINCT CONVERT(VARCHAR, ROW_NUMBER() OVER(PARTITION BY order_ref ORDER BY advice_ref)) [RowNum2]
                FROM    [ED_dups].[dbo].[NewEDDupsLongForm]
            ) rn2 ) rn

    SET @SQL = 'SELECT order_ref' + @SQL + '
                FROM    (   SELECT  order_ref, 
                                    advice_ref, 
                                    case when CONVERT(VARCHAR, ROW_NUMBER() OVER(PARTITION BY order_ref ORDER BY advice_ref)) < 10 
                                         then ''Advice0'' + CONVERT(VARCHAR, ROW_NUMBER() OVER(PARTITION BY order_ref ORDER BY advice_ref))
                                         else ''Advice'' + CONVERT(VARCHAR, ROW_NUMBER() OVER(PARTITION BY order_ref ORDER BY advice_ref)) 
                                         end [AdviceID]
                            FROM    [ED_dups].[dbo].[NewEDDupsLongForm]
                        ) data
                        PIVOT
                        (   MAX(advice_ref)
                            FOR AdviceID IN (' + STUFF(@PVT, 1, 2, '') + ')
                        ) pvt'

    EXECUTE SP_EXECUTESQL @SQL

SQL服务器告诉我查询执行成功,但没有输出。当我运行代码片段时,问题似乎在于枢轴语句,附近 + STUFF(@PVT, 1, 2, '') + ') 和/或在选择语句中,附近 ''Advice0'' +

提前感谢您提供任何帮助 - 我已经有好几天了!

2 个答案:

答案 0 :(得分:2)

我认为你必须初始化像

这样的变量
DECLARE @SQL NVARCHAR(MAX) = ''
DECLARE @PVT NVARCHAR(MAX) = ''

DECLARE @SQL NVARCHAR(MAX)
DECLARE @PVT NVARCHAR(MAX)

SELECT @SQL = '', @PVT = ''

否则您的@SQL将为空

答案 1 :(得分:0)

我想到的第一件事是 - 你真的需要SQL来获取具有动态列数的数据集吗?如果您正在编写应用程序,那么您的用户界面(将其作为网页或桌面应用程序表单)将更好地将您的数据转换为所需的结构。

如果你真的需要这样做,当你不会尝试在一个大而复杂的查询中做所有事情时,你会让生活变得更轻松,而是将它分成一步一步完成的小任务。我要做的是使用临时表来存储工作结果,然后使用游标按顺序处理订单,并在将数据插入临时表或表时按建议提供建议,最后返回此表的内容。将所有内容包装在存储过程中。 此方法还允许您更容易地调试它 - 如果它已完成预期的操作,您可以检查每一步。

最后的建议 - 分享你的NewEDDupsLongForm表的定义 - 有人可能会编写一些代码来帮助你。

欢呼声