Sql pivot-但不要对值求和
我有一个如下所示的表模式Sql pivot-但不要对值求和,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有一个如下所示的表模式 CREATE TABLE [dbo].[Discounts]( [Id] [int] NOT NULL, [ProductId] [varchar(50)] NOT NULL, [LowerBoundDays] [int] NOT NULL, [UpperBoundDays] [int] NOT NULL, [Discount] [decimal](18, 4) NOT NULL, lower
CREATE TABLE [dbo].[Discounts](
[Id] [int] NOT NULL,
[ProductId] [varchar(50)] NOT NULL,
[LowerBoundDays] [int] NOT NULL,
[UpperBoundDays] [int] NOT NULL,
[Discount] [decimal](18, 4) NOT NULL,
lower upper discount(%)
product1 0 10 0
product1 10 30 1
product1 30 60 2
product1 60 90 3
product1 90 120 4
product2 0 10 0
product2 10 30 1
product2 30 60 2
product2 60 90 3
product2 90 120 4
还有一些像这样的数据
CREATE TABLE [dbo].[Discounts](
[Id] [int] NOT NULL,
[ProductId] [varchar(50)] NOT NULL,
[LowerBoundDays] [int] NOT NULL,
[UpperBoundDays] [int] NOT NULL,
[Discount] [decimal](18, 4) NOT NULL,
lower upper discount(%)
product1 0 10 0
product1 10 30 1
product1 30 60 2
product1 60 90 3
product1 90 120 4
product2 0 10 0
product2 10 30 1
product2 30 60 2
product2 60 90 3
product2 90 120 4
如何执行透视查询以获得如下所示的两行:
0-10 10-30 30-60 60-90 90-120
product1 0 1 2 3 4
product2 0 1 2 3 4
因为您使用的是SQL Server,所以有几种方法可以将数据行转换为列 可以将聚合函数与CASE表达式一起使用以获得结果:
select productid,
max(case when lower = 0 and upper = 10 then discount end) [0-10],
max(case when lower = 10 and upper = 30 then discount end) [10-30],
max(case when lower = 30 and upper = 60 then discount end) [30-60],
max(case when lower = 60 and upper = 90 then discount end) [60-90],
max(case when lower = 90 and upper = 120 then discount end) [90-120]
from CorporateSpread
group by productid;
看
如果您使用的是SQL Server 2005+,则可以使用以下功能:
select productid, [0-10], [10-30], [30-60], [60-90],[90-120]
from
(
select productid,
discount,
cast(lower as varchar(10)) + '-' + cast(upper as varchar(10)) rng
from CorporateSpread
) d
pivot
(
max(discount)
for rng in ([0-10], [10-30], [30-60], [60-90],[90-120])
) piv;
看
如果您有已知数量的值,上述两个版本非常有效,但如果您有未知数量的范围,则需要使用动态SQL:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(lower as varchar(10)) + '-' + cast(upper as varchar(10)))
from CorporateSpread
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT productid, ' + @cols + '
from
(
select productid,
discount,
cast(lower as varchar(10)) + ''-'' + cast(upper as varchar(10)) rng
from CorporateSpread
) x
pivot
(
max(discount)
for rng in (' + @cols + ')
) p '
execute sp_executesql @query;
看。所有版本将给出一个结果:
| PRODUCTID | 0-10 | 10-30 | 30-60 | 60-90 | 90-120 |
-----------------------------------------------------
| product1 | 0 | 1 | 2 | 3 | 4 |
| product2 | 0 | 1 | 2 | 3 | 4 |
这不意味着你的查询必须了解数据吗。如中所示,您必须将日期范围硬编码到case表达式中。如果不同的产品有不同的日期范围怎么办。有没有更具动态性的方法?@ChrisCa查看我的编辑,我使用PIVOT函数添加了两个版本,一个版本使用动态SQL