sql server 中的数据透视表

发布于 2024-08-17 15:20:47 字数 571 浏览 7 评论 0原文

是的,我已经尝试过代码。我的要求是用户输入年份和月份&价格按日期显示在当年和月份的列中,第一列为 CompetitorID。我希望我的结果如下:

Competitors | day1  | day2  | day3  | day4 ..............|day31
================================================================
competitor 1| Price | Price | price | price..............|price 
competitor 2| Price | Price | price | price..............|price
competitor 3| Price | Price | price | price..............|price 
competitor 4| Price | Price | price | price..............|price

我的表结构是:

COMPETITORDETAIL (ID, CompetitorID, oDate, Price)

Yes I've tried the code. My requirement is that user inputs Year and Month & prices are shown date-wise in columns for that year and month, with first column as CompetitorID. I want my result like:

Competitors | day1  | day2  | day3  | day4 ..............|day31
================================================================
competitor 1| Price | Price | price | price..............|price 
competitor 2| Price | Price | price | price..............|price
competitor 3| Price | Price | price | price..............|price 
competitor 4| Price | Price | price | price..............|price

My Table structure is:

COMPETITORDETAIL (ID, CompetitorID, oDate, Price)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

埖埖迣鎅 2024-08-24 15:20:47

这容易多了。我编写了一个名为 pivot_query 的存储过程,它使 PIVOT 在 SQL Server 2005+ 中更易于使用。该过程的来源是这里,一些如何使用它的示例是< a href="http://dot-dash-dot.com/files/pivot_query_examples.sql" rel="nofollow noreferrer">此处。

对于您的代码示例:

create table Competitors
   (
   CompetitorId      integer identity,
   Name              varchar(30)
   )

insert into Competitors values ('Bobs Discount Emporium')
go
insert into Competitors values ('Joes Really Cheap Crap')
go

create table CompetitorDetail
   (
   Id                integer identity,
   CompetitorId      integer,
   oDate             datetime,
   Price             decimal(12,3)
   )

insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go

declare @mySQL varchar(MAX)

set @mySQL = '
select
   c.Name,
   right(cast(month(cd.oDate) + 100 as varchar(3)),2) + ''_'' + right(cast(day(cd.oDate) + 100  as varchar(3)),2) mon_day,
   cd.Price
from
   Competitors c

   JOIN CompetitorDetail cd
      on (cd.CompetitorId = c.CompetitorId )
   ';

exec pivot_query @mySQL, 'Name', 'Mon_Day', 'max(Price) MaxP,min(Price) MinP'

结果是:

Name                           01_09_MaxP   01_09_MinP   01_11_MaxP   01_11_MinP   01_13_MaxP   01_13_MinP   01_17_MaxP   01_17_MinP   
------------------------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ 
Bobs Discount Emporium         10.000       10.000       11.000       11.000       12.000       12.000       13.000       13.000       
Joes Really Cheap Crap         14.000       14.000       15.000       15.000       16.000       16.000       18.000       18.000       

希望有帮助!

This is a lot easier. I wrote a stored proc named pivot_query that makes PIVOT a lot easier to use for SQL Server 2005+. The source for the proc is here, some examples how to use it are here.

For your code example:

create table Competitors
   (
   CompetitorId      integer identity,
   Name              varchar(30)
   )

insert into Competitors values ('Bobs Discount Emporium')
go
insert into Competitors values ('Joes Really Cheap Crap')
go

create table CompetitorDetail
   (
   Id                integer identity,
   CompetitorId      integer,
   oDate             datetime,
   Price             decimal(12,3)
   )

insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-10, 10.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-8, 11.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-6, 12.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (1, getdate()-2, 13.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-10, 14.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-8, 15.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-6, 16.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go
insert into CompetitorDetail values (2, getdate()-2, 18.00)
go

declare @mySQL varchar(MAX)

set @mySQL = '
select
   c.Name,
   right(cast(month(cd.oDate) + 100 as varchar(3)),2) + ''_'' + right(cast(day(cd.oDate) + 100  as varchar(3)),2) mon_day,
   cd.Price
from
   Competitors c

   JOIN CompetitorDetail cd
      on (cd.CompetitorId = c.CompetitorId )
   ';

exec pivot_query @mySQL, 'Name', 'Mon_Day', 'max(Price) MaxP,min(Price) MinP'

which results in:

Name                           01_09_MaxP   01_09_MinP   01_11_MaxP   01_11_MinP   01_13_MaxP   01_13_MinP   01_17_MaxP   01_17_MinP   
------------------------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ ------------ 
Bobs Discount Emporium         10.000       10.000       11.000       11.000       12.000       12.000       13.000       13.000       
Joes Really Cheap Crap         14.000       14.000       15.000       15.000       16.000       16.000       18.000       18.000       

Hope that helps!

乜一 2024-08-24 15:20:47

如果您使用 Microsoft SQL-Server,则有一个枢轴函数。但列是静态定义的,因此它的使用受到限制。 (请参阅http://technet.microsoft.com/en-us/library/ ms177410.aspx

有动态SQL的解决方案,但我最终在代码中解决了这个问题。

If you'r working with Microsoft SQL-Server there is a pivot function. But the columns are defined statically, so it's use is limited. (See http://technet.microsoft.com/en-us/library/ms177410.aspx)

There are solutions with dynamic SQL, but i solved this in the code eventually.

瑶笙 2024-08-24 15:20:47

对于 SQL Server 2005、2008

要测试的表和一些数据

CREATE TABLE CompetitorDetail
  ( 
   ID int
  ,CompetitorID int
  ,oDate datetime
  ,Price decimal(19, 4)
  )

INSERT INTO  CompetitorDetail
      ( ID, CompetitorID, oDate, Price )
SELECT  1, 1, '2010-01-01', 100.0 UNION
SELECT  2, 1, '2010-01-02', 110.0 UNION
SELECT  3, 1, '2010-01-03', 99.0 UNION
SELECT  4, 2, '2010-01-01', 102.2 UNION
SELECT  5, 2, '2010-01-02', 112.2 UNION
SELECT  6, 2, '2010-01-03', 99.2 UNION
SELECT  7, 3, '2010-01-01', 100.3 UNION
SELECT  8, 3, '2010-01-02', 110.3 UNION
SELECT  9, 3, '2010-01-03', 99.3 ;

周期的开始和天数

/* First day of the peroid */
DECLARE @StartDate datetime
    ,@NumberOfDays int

SET @StartDate = '2010-01-01'
SET @NumberOfDays = 31

动态列 = 动态 sql

/* Table to compose dynamic query */
DECLARE @qw TABLE
  ( 
   id int IDENTITY(1, 1)
  ,txt nvarchar(500)
  )

/* Start composing dynamic query */
INSERT  INTO @qw ( txt ) VALUES  ( 'SELECT' ) 
INSERT  INTO @qw ( txt ) VALUES  ( 'CompetitorID' )

继续编写动态查询

/* Helpers */
DECLARE
  @dte datetime
 ,@str varchar(10)
 ,@i int


/* Compose dynamic query */
SET @i = 0
WHILE @i < @NumberOfDays 
  BEGIN
    SET @dte = DATEADD(d, @i, @StartDate)
    SET @str = CONVERT(varchar(10), @dte, 121)  
    INSERT  INTO @qw ( txt )
            SELECT  ',MAX(CASE oDate WHEN ''' + @str + ''' THEN Price ELSE NULL END) AS [' + @str + ']'

    SET @i = @i + 1
  END

/* Finish the dynamic query */
INSERT  INTO @qw (txt) VALUES ( 'FROM  CompetitorDetail' )
INSERT  INTO @qw (txt) VALUES ( 'GROUP BY CompetitorID' )
INSERT  INTO @qw (txt) VALUES ( 'ORDER BY CompetitorID' )

连接到变量并执行

/* Create a variable with dynamic sql*/
DECLARE @exe nvarchar(4000)
SET @exe=''
SELECT  @exe = @exe + txt + ' ' FROM @qw ORDER BY id


/* execute dynamic sql */
EXEC sp_executesql @exe

返回

CompetitorID 2010-01-01   2010-01-02   2010-01-03   2010-01-04  ...  2010-01-31 
------------ ----------   ----------   ----------   ----------  ...  ---------- 
1            100.0000     110.0000     99.0000      NULL        ...  NULL       
2            102.2000     112.2000     99.2000      NULL        ...  NULL       
3            100.3000     110.3000     99.3000      NULL        ...  NULL       

For SQL Server 2005, 2008

The table and some data to test

CREATE TABLE CompetitorDetail
  ( 
   ID int
  ,CompetitorID int
  ,oDate datetime
  ,Price decimal(19, 4)
  )

INSERT INTO  CompetitorDetail
      ( ID, CompetitorID, oDate, Price )
SELECT  1, 1, '2010-01-01', 100.0 UNION
SELECT  2, 1, '2010-01-02', 110.0 UNION
SELECT  3, 1, '2010-01-03', 99.0 UNION
SELECT  4, 2, '2010-01-01', 102.2 UNION
SELECT  5, 2, '2010-01-02', 112.2 UNION
SELECT  6, 2, '2010-01-03', 99.2 UNION
SELECT  7, 3, '2010-01-01', 100.3 UNION
SELECT  8, 3, '2010-01-02', 110.3 UNION
SELECT  9, 3, '2010-01-03', 99.3 ;

Start of the period and number of days

/* First day of the peroid */
DECLARE @StartDate datetime
    ,@NumberOfDays int

SET @StartDate = '2010-01-01'
SET @NumberOfDays = 31

Dynamic columns = dynamic sql

/* Table to compose dynamic query */
DECLARE @qw TABLE
  ( 
   id int IDENTITY(1, 1)
  ,txt nvarchar(500)
  )

/* Start composing dynamic query */
INSERT  INTO @qw ( txt ) VALUES  ( 'SELECT' ) 
INSERT  INTO @qw ( txt ) VALUES  ( 'CompetitorID' )

Continue composing the dynamic query

/* Helpers */
DECLARE
  @dte datetime
 ,@str varchar(10)
 ,@i int


/* Compose dynamic query */
SET @i = 0
WHILE @i < @NumberOfDays 
  BEGIN
    SET @dte = DATEADD(d, @i, @StartDate)
    SET @str = CONVERT(varchar(10), @dte, 121)  
    INSERT  INTO @qw ( txt )
            SELECT  ',MAX(CASE oDate WHEN ''' + @str + ''' THEN Price ELSE NULL END) AS [' + @str + ']'

    SET @i = @i + 1
  END

/* Finish the dynamic query */
INSERT  INTO @qw (txt) VALUES ( 'FROM  CompetitorDetail' )
INSERT  INTO @qw (txt) VALUES ( 'GROUP BY CompetitorID' )
INSERT  INTO @qw (txt) VALUES ( 'ORDER BY CompetitorID' )

Concatenate into a variable and execute

/* Create a variable with dynamic sql*/
DECLARE @exe nvarchar(4000)
SET @exe=''
SELECT  @exe = @exe + txt + ' ' FROM @qw ORDER BY id


/* execute dynamic sql */
EXEC sp_executesql @exe

Returns

CompetitorID 2010-01-01   2010-01-02   2010-01-03   2010-01-04  ...  2010-01-31 
------------ ----------   ----------   ----------   ----------  ...  ---------- 
1            100.0000     110.0000     99.0000      NULL        ...  NULL       
2            102.2000     112.2000     99.2000      NULL        ...  NULL       
3            100.3000     110.3000     99.3000      NULL        ...  NULL       
慵挽 2024-08-24 15:20:47
CASE 
WHEN SQL Server 2005 OR 2008 THEN Use Pivot 
WHEN Oracle THEN Use LIKE MAX(Decode(Day=1,Data,0) as Day1 and GROUP BY Day
WHEN SQL Server 2000 THEN Use LIKE MAX(CASE WHEN Day = 1 THEN Data ELSE 0 End) As Day1 and GROUP BY Day 
END
CASE 
WHEN SQL Server 2005 OR 2008 THEN Use Pivot 
WHEN Oracle THEN Use LIKE MAX(Decode(Day=1,Data,0) as Day1 and GROUP BY Day
WHEN SQL Server 2000 THEN Use LIKE MAX(CASE WHEN Day = 1 THEN Data ELSE 0 End) As Day1 and GROUP BY Day 
END
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文