TSQL:如何自动添加选择列

时间:2013-09-20 07:26:58

标签: sql sql-server-2008 tsql

我遇到了问题但无法解决。此外,我无法在互联网的任何地方找到答案。

简化我有一个带有coloumns的大表,其中带有ID的产品的值按年存储:

  • ID

在我的存储过程中,获取信息的属性是:

  • @year
  • @id

如果您想获得有关多个产品的信息,可以使用逗号分隔的产品ID列表,如('654654,543543,987987')。

我的TSQL应该是这样的:

select year, 
    sum(case when id = @id[1] then value), 
    sum(case when id = @id[2] then value), 
    [...]
from table myTable
where year = @year 
group by year 
order by year

我想做的是迭代逗号分隔的id,对于每个id,我想添加一个像这样的新的select attribut(sum(id = @id [x]然后是value的情况)。

你可以帮我解决这个问题吗?有什么建议可以解决吗?!

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

PIVOT操作可以简化查询。

但是,无论如何,构建这样的查询的唯一方法似乎是使用动态SQL。

DECLARE
    @Ids NVARCHAR(MAX),
    @stmt NVARCHAR(MAX)

SET @Ids = '1,2'

-- Transform Ids into the format PIVOT understands - with square brackets.
-- Primitive way, to not overcomplicate sample.
SET @Ids = '[' + REPLACE(@Ids, ',', '], [') + ']'
PRINT @Ids -- [1], [2]

SET @Stmt = '
  SELECT *
  FROM Products as p
  PIVOT 
  (
      SUM(p.Value)
      FOR p.Id IN (' + @Ids + ')
  ) AS t
  ORDER BY Year'


EXEC sp_executesql @Stmt

如果您需要更准确的方法将逗号分隔列表拆分为数组(表格),请参阅此article了解详细信息。

此示例可在SQL Fiddle

上找到

答案 1 :(得分:0)

在使用存储过程时,可以使用sp_executesql执行dynimically build SQL语句。

所以,你必须像这样迭代CSV:

DECLARE @List NVARCHAR(MAX) = N'1001,dada,1002,1003'
DECLARE @ProductsID TABLE ( [ID] BIGINT )


DECLARE @XML xml = N'<r><![CDATA[' + REPLACE(@List, ',', ']]></r><r><![CDATA[') + ']]></r>'

INSERT INTO @ProductsID ([ID])
SELECT DISTINCT CAST(Tbl.Col.value('.', 'float') AS bigint)
FROM @xml.nodes('//r') Tbl(Col)
WHERE ISNUMERIC(Tbl.Col.value('.', 'varchar(max)')) = 1

SELECT [ID] FROM @ProductsID 

然后,使用具有ID的表来动态构建SQL语句并执行它。