2010-01-05 6 views
2

Je vais avoir du mal à obtenir ma tête autour d'une requête im essayant de construire avec SQL Server 2005.SQL Pivot question

J'ai une table, permet d'appeler ses ventes:

SaleId (int) (pk) EmployeeId (int) SaleDate (datetime)

Je souhaite produire un rapport répertoriant le nombre total de ventes réalisées par un employé pour chaque jour dans une plage de données donnée.

Ainsi, par exemple, je veux le voir toutes les ventes dans le 1er Décembre 2009 - 31 Décembre 2009 avec une sortie comme:

EmployeeId Dec1 Dec2 Dec3 Dec4 

1   10 10 1  20 
2   25 10 2  2 

..etc mais les dates doivent être flexibles.

Je me suis trompé avec l'utilisation de pivot, mais je n'arrive pas à l'obtenir, toutes les idées sont les bienvenues!

Répondre

4

Voici un exemple complet. Vous pouvez modifier la plage de dates pour l'adapter à vos besoins.

use sandbox; 
create table sales (SaleId int primary key, EmployeeId int, SaleAmt float, SaleDate date); 

insert into sales values (1,1,10,'2009-12-1'); 
insert into sales values (2,1,10,'2009-12-2'); 
insert into sales values (3,1,1,'2009-12-3'); 
insert into sales values (4,1,20,'2009-12-4'); 

insert into sales values (5,2,25,'2009-12-1'); 
insert into sales values (6,2,10,'2009-12-2'); 
insert into sales values (7,2,2,'2009-12-3'); 
insert into sales values (8,2,2,'2009-12-4'); 

SELECT * FROM 
     (SELECT EmployeeID, DATEPART(d, SaleDate) SaleDay, SaleAmt 
        FROM sales 
        WHERE SaleDate between '20091201' and '20091204' 
       ) src 
PIVOT (SUM(SaleAmt) FOR SaleDay 
IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31])) AS pvt; 

Résultats (en fait 31 colonnes (pour tous les jours de mois possible) seront listés, mais je suis juste montrer 4 premiers):

EmployeeID  1  2  3  4 
1    10  10  1  20 
2    25  10  2  2 
+0

hey c'est super ... je n'arrivais pas à trouver comment générer les colonnes de manière dynamique - c'est ce que vous avez fait, bravo! –

+0

@Roland Bouman - merci :) – dcp

1

Je bricolé un peu, et je pense que cela est comment vous pouvez le faire avec PIVOT:

select employeeid 
,  [2009/12/01] as Dec1 
,  [2009/12/02] as Dec2 
,  [2009/12/03] as Dec3 
,  [2009/12/04] as Dec4 
from sales pivot (
     count(saleid) 
     for saledate 
     in ([2009/12/01],[2009/12/02],[2009/12/03],[2009/12/04]) 
    ) as pvt 

(ceci est ma table:

CREATE TABLE [dbo].[sales](
[saleid] [int] NULL, 
[employeeid] [int] NULL, 
[saledate] [date] NULL 

les données sont: 10 lignes pour '2009/12/01' pour emp1, 25 lignes pour '2009/12/01' pour emp2, 10 lignes pour '2009/12/02' pour emp1, etc.)

Maintenant, je dois dire, c'est la première fois que j'ai utilisé PIVOT et peut-être que je ne comprends pas, mais cela me semble plutôt inutile. Je veux dire, à quoi bon avoir un tableau croisé si vous ne pouvez rien faire pour spécifier les colonnes dynamiquement?

EDIT: réponse ok-dcp le fait. L'astuce est, vous n'avez pas besoin de nommer explicitement les colonnes dans la liste SELECT, * sera en fait correctement déployer vers une colonne pour la première colonne 'non pivotée', et une colonne générée dynamiquement pour chaque valeur qui apparaît dans le FOR .. Clause IN dans la construction PIVOT.

+0

Tous les éléments potentiels doivent être listés dans la clause FOR..IN. Tu as raison, ce n'est pas dynamique. Mais quand je vois PIVOT utilisé dans une instruction SQL, je sais ce qu'il essaie de faire. Sinon, un tas d'instructions Case pourrait être en train d'essayer de faire quelque chose (Oh j'ai oublié, il suffit de regarder la documentation.). Belle première tentative. +1 – JeffO

+0

Merci GuinnessFan. Oui, je connais les instructions CASE pour faire la même chose avec MySQL. Mais quand même, c'est sympa de pouvoir avoir une syntaxe explicite pour ça. Merci encore! Bravo –

+0

C'est parfait, merci. – chrr