2013-09-25 118 views
2

我有以下SQL查询创建的列出现故障,我不太清楚如何解决它。为动态数据透视表排序

SELECT rhead.rhcust AS [Cust ID], rdetl.rdextp AS [Inv Amt], rhead.rhivdt AS [Inv Date] 
INTO #TempTable 
FROM rhead 
LEFT OUTER JOIN rdetl 
    ON rhead.rhinvc = rdetl.rdinvc 
WHERE rhead.rhivdt >= '01-01-2012' AND rhead.rhivdt <= '12-25-12' 

ALTER DATABASE Vista_TM SET COMPATIBILITY_LEVEL = 100 

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Month'+cast(DATEPART(m, [Inv Date]) as varchar(2))) 
        from #TempTable 
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

set @query = 'SELECT [Cust ID],' + @cols + ' 
      from 
      (
       SELECT [Cust ID], [Inv Amt], 
        ''Month''+cast(DATEPART(m, [Inv Date]) as varchar(2)) MonthNo 
       FROM #TempTable 
      ) x 
      pivot 
      (
       sum([Inv Amt]) 
       for MonthNo in (' + @cols + ') 
      ) p ' 

execute(@query) 

DROP TABLE #TempTable 

我相信它有做一些与查询的这个部分:

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Month'+cast(DATEPART(m, [Inv Date]) as varchar(2))) 
        from #TempTable 
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

我曾尝试与张贴在此topic答案乱搞,但我无法得到查询运行。我希望有人能帮忙。

编辑我只注意到我行是出的订单,并希望通过[自定义ID]以及排序。

+0

您的想法是对的,您可以在'#TempTable'之后但在FOR XML PATH('')'之前添加'ORDER BY DATEPART(m,[Inv Date])'。在一个不相关的,也不是非常重要的说明中,我认为最好使用'EXECUTE SP_EXECUTESQL @ Query',而不是'EXECUTE(@Query)',[Aaron Bertrand](http://stackoverflow.com/users/ 61305 /)也有[博客关于它](http://sqlblog.com/blogs/aaron_bertrand/archive/2011/09/17/bad-habits-to-kick-using-exec-instead-of-sp-executesql .aspx)在他的坏习惯踢系列。 – GarethD

回答

6

您可以通过添加ORDER BY调整动态透视查询字段的顺序当您设置@cols字符串:

select @cols = STUFF((SELECT distinct ',' + QUOTENAME('Month'+cast(DATEPART(m, [Inv Date]) as varchar(2))) 
        from #TempTable 
        ORDER BY .... 
      FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

更新:错过了DISTINCT首先,使用DISTINCT当你有使用子查询,然后ORDER BY

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(ColName) 
        FROM (SELECT DISTINCT 'Month'+cast(DATEPART(m, [Inv Date]) as varchar(2)) ColName 
          FROM #TempTable 
         )sub 
        ORDER BY ColName 
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'') 

您可能需要一个“排序”字段添加到您的子查询,如果你不能简单地使用列名,你可以添加任何字段的S ubquery,只要它们不会破坏DISTINCT列表。例如:

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(ColName) 
        FROM (SELECT DISTINCT 'Month'+cast(DATEPART(m, [Inv Date]) as varchar(2)) ColName 
              ,CASE WHEN field = 'something' THEN 1 
               WHEN field = 'something else' THEN 2 
               ELSE 3 
              END as Sort 
              ,Cust_ID 
          FROM #TempTable 
         )sub 
        ORDER BY Sort,Cust_ID 
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)') ,1,1,'') 
+0

在我特别的例子中,我试过ORDER BY'[Inv Date]'和'QUOTENAME'都没有工作,错误消息说_ORDER BY项必须出现在选择列表中,如果SELECT DISTINCT被指定._我也试过'[Inv Amt]' – Matt

+0

@Matt首先错过了你的'DISTINCT',看到更新。 –

+0

这种感谢!不幸的是,我这么做了几个月,所以第10,11,12个月在第1个月后出现。 – Matt