2010-01-14 171 views
1

是的我試過了代碼。我的要求是,用戶輸入年份和月份&價格以日期顯示在該年份和月份的列中,第一列作爲競爭者ID。我想我的結果,如:在sql server中樞軸

 
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)

+0

你想只顯示一個特定的月份或所有月份/天嗎?是否應該在沒有條目的日子顯示列?這是動態的,還是固定的列和日期*(例如,你只想看到2009年1月的值)*?您需要顯示一些示例數據和預期輸出。 – 2010-01-14 06:48:07

+0

我已經顯示了輸出。用戶將輸入年份和月份,並且查詢將產生上述格式,即第一列中的競爭對手和其餘列中的該年份和月份的日期(1到31)。 – hotcoder 2010-01-14 06:57:52

回答

2

這是一個容易得多。我寫了一個名爲pivot_query的存儲過程,這使得PIVOT更容易用於SQL Server 2005+。 proc的來源是here,一些示例如何使用它是here

對於您的代碼示例:

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  

希望幫助!

0
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 
0

對於SQL Server 2005,2008

表和一些數據,以測試天

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

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

動態列=動態的期限和數量的

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 ; 

開始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