0

我有问题,无法解决。此外,我在互联网上的任何地方都找不到答案。

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

  • ID
  • 价值

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

  • @年
  • @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,我想像这样添加一个新的选择属性(sum(当 id = @id[x] 然后值时的情况)。

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

谢谢你的帮助!

4

2 回答 2

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

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

此示例在SQL Fiddle上可用

于 2013-09-20T08:26:28.703 回答
0

当您使用存储过程时,您可以使用sp_executesql动态执行构建 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 语句并执行它。

于 2013-09-20T07:39:20.217 回答