2010-06-27 8 views
0

J'ai la table de vente qui consiste, ItemSize, GroupName, quantité, ProductID, etc ...requête SQL pour afficher les ventes de produits

Maintenant, je veux afficher les ventes selon le format suivant

GroupName ItemSize Quantity ItemSize Quantity 

moyens

BEER 350ml 500 650ml 1000 

Comment puis-je parvenir dans SQL Server 2005 Express (T-SQL)? Merci

MISE À JOUR:

sa ma structure de table de vente

CREATE TABLE [dbo].[SalesLog](
[SalesID] [int] IDENTITY(1,1) NOT NULL, 
[MemoNo] [int] NULL, 
[ProductCode] [int] NULL, 
[Quantity] [int] NULL, 
[Price] [int] NULL, 
[ProductGroup] [int] NULL, 
    CONSTRAINT [PK_SalesLog] PRIMARY KEY CLUSTERED 
    (
     [SalesID] ASC 
    ) WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

sa ma structure table de produit

CREATE TABLE [dbo].[Products](
[ProductId] [int] IDENTITY(1,1) NOT NULL, 
[pName] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
[pSize] [int] NULL, 
[pPrice] [int] NULL, 
[pPackQty] [int] NULL, 
[pGroup] [int] NULL, 
[pCode] [int] NULL, 
[pStock] [int] NULL, 
[pYrStock] [int] NULL, 
[pClearStock] [int] NULL, 
    CONSTRAINT [PK_Products] PRIMARY KEY CLUSTERED 
    (
    [ProductId] ASC 
    ) WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 
+0

Votre question doit être clarifiée. Je pense que je sais ce que vous demandez, mais j'ai dû le regarder longtemps. Quelle est la définition de la table? Inclure quelques rangées de données d'échantillon serait également une bonne idée. –

+0

Je ne pense pas que vous pouvez utiliser ItemSize et Quantity deux fois. Vous devrez peut-être avoir des noms uniques pour pouvoir faire pivoter les données. –

+0

J'ai une application basée sur foxpro qui imprime des données au même format et stocke les données de la même manière que moi. –

Répondre

3

Vous pouvez agréger les données en utilisant les instructions SUM et CASE.

Utilisation de définitions de table (et quelques très minimes composées de données), voici un exemple de la façon dont vous pourriez le faire:

--** Create test tables 
DECLARE @SalesLog TABLE ( 
SalesID int IDENTITY(1,1) NOT NULL, 
MemoNo int NULL, 
ProductCode int NULL, 
Quantity int NULL, 
Price int NULL, 
ProductGroup int NULL) 

DECLARE @Products TABLE( 
ProductId int IDENTITY(1,1) NOT NULL, 
pName nvarchar(50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
pSize int NULL, 
pPrice int NULL, 
pPackQty int NULL, 
pGroup int NULL, 
pCode int NULL, 
pStock int NULL, 
pYrStock int NULL, 
pClearStock int NULL) 

--** Setup test data 
INSERT INTO @SalesLog (MemoNo, ProductCode, Quantity, Price, ProductGroup) 
SELECT 0, 1, 500, 0, 1 UNION 
SELECT 0, 2, 700, 0, 1 UNION 
SELECT 0, 2, 333, 0, 1 UNION 
SELECT 0, 3, 200, 0, 2 UNION 
SELECT 0, 4, 125, 0, 2 ; 

INSERT INTO @Products (pName, pSize, pPrice, pPackQty, pGroup, pCode, pStock, pYrStock, pClearStock) 
SELECT 'Beer', 350, 1 , 1, 1, 1, 0, 0, 0 UNION 
SELECT 'Beer', 650, 1 , 1, 1, 2, 0, 0, 0 UNION 
SELECT 'Beer', 1000, 1 , 1, 1, 3, 0, 0, 0 UNION 
SELECT 'Wine', 750, 1 , 1, 2, 4, 0, 0, 0 UNION 
SELECT 'Wine', 1000, 1 , 1, 2, 5, 0, 0, 0 ; 

--** Example query 
SELECT t.pName AS 'Product' 
    , MAX(CASE WHEN t.Col = 1 THEN t.pSize END) AS 'Item Size' 
    , ISNULL(SUM(CASE WHEN t.Col = 1 THEN t.Quantity END),0) AS 'Quantity' 
    , MAX(CASE WHEN t.Col = 2 THEN t.pSize END) AS 'Item Size' 
    , ISNULL(SUM(CASE WHEN t.Col = 2 THEN t.Quantity END),0) AS 'Quantity' 
    , MAX(CASE WHEN t.Col = 3 THEN t.pSize END) AS 'Item Size' 
    , ISNULL(SUM(CASE WHEN t.Col = 3 THEN t.Quantity END),0) AS 'Quantity' 
FROM (
SELECT pName 
    , pCode 
    , pGroup 
    , pSize 
    , sl.Quantity 
    , DENSE_RANK() OVER(PARTITION BY p.pGroup ORDER BY p.pSize) AS Col 
    FROM @Products AS p 
    LEFT JOIN @SalesLog AS sl 
    ON p.pGroup = sl.ProductGroup 
    AND p.pCode = sl.ProductCode 
    ) AS t 
GROUP BY t.pGroup 
    , t.pName 
; 

La requête utilise la fonction DENSE_RANK aux éléments du groupe d'une taille ensemble et pour les ordonner en ordre de taille et cela est utilisé pour déterminer dans quelle colonne les données doivent être écrites.

Bien qu'il existe un opérateur PIVOT dans SQL Server 2005 et versions ultérieures, il n'est pas très utile lorsque vous avez différents types d'en-tête de colonne (taille de l'élément et quantité dans ce cas).

Vous devrez décider du nombre maximum de tailles de produits que vous souhaitez signaler car cela est codé en dur dans la requête. Donc, si le nombre maximum de tailles de produit est 3, vous codez la requête comme indiqué ci-dessus. Si, cependant, un de vos produits a 4 tailles différentes, alors vous allez ajouter une paire supplémentaire de taille et de quantité de colonnes pour t.Col = 4 et ainsi de suite.

J'espère que cela aide.

+0

La sortie est exactement ce que je veux, mais l'éditeur de requête SQL-Server renvoie une erreur en utilisant plusieurs instructions de valeurs. cette requête fonctionne sur les données disponibles dans l'énoncé de la requête, comment puis-je l'utiliser pour mes données existantes à partir des tables de base de données Products, SalesLog .. Merci –

+0

Je suis très désolé de la création des données de test n'étant pas compatible avec SQL Server 2005. J'ai modifié pour qu'il fonctionne maintenant pour SQL Server 2005. – JonPayne

+0

En ce qui concerne l'utilisation de la requête avec vos tables existantes, remplacez les variables de table par vos tables de base de données. Il suffit donc de remplacer @Products par Products et @SalesLog par SalesLog. – JonPayne

1

Il semble que vous essayez de faire un tableau croisé dynamique, où les différents Les tailles d'élément sont représentées par des colonnes différentes plutôt que par des lignes. Jetez un oeil à http://msdn.microsoft.com/en-us/library/ms177410.aspx

+0

mes données sont réparties sur 3 tables, PIVOT sera en mesure de le faire. –

Questions connexes