2010-01-14 6 views
1

Oui J'ai essayé le code. Mon exigence est que les entrées des utilisateurs pour l'année et le mois soient affichées en colonnes pour cette année et ce mois, avec la première colonne comme CompetitorID. Je veux que mon résultat comme:Pivot dans le serveur SQL

 
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 

Ma structure de table est:

COMPETITORDETAIL (ID, CompetitorID, oDate, Price)

+0

Voulez-vous le montrer pour un mois spécifique, ou pour tous les mois/jours? Devrait-il afficher des colonnes pour les jours où il n'y a pas d'entrées? Est-ce que ce sera dynamique, ou pour des colonnes fixes et des dates * (par exemple, vous voulez seulement voir les valeurs de Jan 2009) *? Vous devez montrer quelques exemples de données et la sortie attendue. –

+0

J'ai montré la sortie. L'utilisateur saisira l'année et le mois et la requête entraînera le format ci-dessus, c'est-à-dire que les concurrents dans la première colonne et le reste des colonnes seront des dates (1 à 31) pour cette année et ce mois. – hotcoder

Répondre

2

C'est beaucoup plus facile. J'ai écrit un proc stocké nommé pivot_query qui rend PIVOT beaucoup plus facile à utiliser pour SQL Server 2005+. La source pour le proc est here, quelques exemples comment l'utiliser sont here.

Pour votre exemple de code:

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' 

qui se traduit par:

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!

0

Si you'r travaille avec Microsoft SQL-Serveur, il est fonction de pivot. Mais les colonnes sont définies statiquement, donc son utilisation est limitée. (Voir http://technet.microsoft.com/en-us/library/ms177410.aspx)

Il existe des solutions avec SQL dynamique, mais j'ai finalement résolu cela dans le code.

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

Pour SQL Server 2005, 2008

Le tableau et des données pour tester

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 ; 

Début de la période et le nombre de jours

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

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

colonnes dynamiques = dynamiques

/* 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') 

continuer à composer la requête dynamique

/* 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 dans une variable et 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 

Retours

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