2010-06-30 4 views
0

cette question est basée sur la réponse obtenu à partir d'un autre SO question, can be found here.sql requête pour le résumé des ventes à nouveau

J'ai réussi à écrire une requête réponse moi-même sur la base condition

Select s.pName, 
     s.ProductCode, 
     min(s.Price)       as MinPrice, 
     sum(s.Quantity)      as SalesQty, 
     sum(s.Price * s.Quantity)   as SalesValue, 
     isnull((select sum(Quantity) 
       from Breakages 
       where pGroup = 16 
         and quantity > 0), 0) as BreakQty, 
     isnull((select sum(Price * Quantity) 
       from Breakages 
       where pGroup = 16), 0)  as BreakValue, 
     isnull((select CASE 
         WHEN min(r.Quantity) != 0 THEN Sum(r.Quantity) 
         END), 0)    as ReturnQty, 
     isnull((select sum(Price * Quantity) 
       from SalesReturn 
       where pGroup = 16), 0)  as ReturnValue 
from SalesLog as s 
     INNER JOIN SalesReturn as r 
     ON r.BillDate = s.BillDate 
     INNER JOIN Breakages as b 
     ON r.BillDate = b.BillDate 
where s.BillDate = '12-10-2010' 
     and r.BillDate = '12-10-2010' 
     and b.BillDate = '12-10-2010' 
     and s.pGroup = 16 
     and b.pGroup = 16 
     and r.pGroup = 16 
group by s.pName, 
      s.ProductCode; 

Voici la sortie de requête ci-dessus

Name    Code Price SalesQty SValue BreakQty BValue RefundQty RQty 
CDM 42GRMS.  854 15  3  45  2  0   3  30 
APPLE JUICE 750ML 860 59  5  295  2  0   3  30 
BISLERI WATER  865  3  5  15  2  0   3  30 
PERK 35 GRMS  870 10  20  200  2  0   3  30 

il y a un problème avec la sortie que vous ne pouvez pas obtenir , Ruptures est de 2 pour le code = 865 et Remboursement est de 3 pour 870 mais toutes les lignes ont des ruptures et des remboursements.

vous pouvez trouver des expériences dans ma requête. merci ........ attente répondre vient

SalesRetrun Tableau

CREATE TABLE [dbo].[SalesReturn](
    [srID] [int] IDENTITY(1,1) NOT NULL, 
    [ProductCode] [int] NULL, 
    [Quantity] [int] NULL, 
    [pGroup] [int] NULL, 
    [MemoNo] [int] NULL, 
    [SalesmanID] [int] NULL, 
    [Price] [int] NULL, 
    [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [AddedOn] [datetime] NULL, 
CONSTRAINT [PK_SalesReturn] PRIMARY KEY CLUSTERED 
([srID] ASC) WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

SalesLog Tableau

CREATE TABLE [dbo].[SalesLog](
    [SalesID] [int] IDENTITY(1,1) NOT NULL, 
    [MemoNo] [int] NULL, 
    [ProductCode] [int] NULL, 
    [Quantity] [int] NULL, 
    [Price] [int] NULL, 
    [pGroup] [int] NULL, 
    [pName] [nvarchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [pSize] [int] NULL, 
    [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
CONSTRAINT [PK_SalesLog] PRIMARY KEY CLUSTERED 
( [SalesID] ASC)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

Ruptures Tableau

CREATE TABLE [dbo].[Breakages](
    [breakId] [int] IDENTITY(1,1) NOT NULL, 
    [MemoNo] [int] NULL, 
    [SalesmanID] [int] NULL, 
    [ProductCode] [int] NULL, 
    [pName] [nvarchar](30) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [Quantity] [int] NULL, 
    [Price] [int] NULL, 
    [pGroup] [int] NULL, 
    [BillDate] [nchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL, 
    [AddedOn] [datetime] NULL, 
CONSTRAINT [PK_Breakages_1] PRIMARY KEY CLUSTERED (
[breakId] ASC)WITH (PAD_INDEX = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

QUERY MISE À JOUR
J'ai ajouté de référence de table et montre un résultat souhaité, mais sa montrant tous les produits que toute vente ou rupture ou remboursement a eu lieu ou non cette date.

Je ne veux pas afficher les lignes où il n'y a aucune vente ou aucune casse ou aucun remboursement. Cela réduira la taille de mon rapport. Courant montrant 319 lignes, mais après le retrait des lignes (calcul manuellement) selon ma logique, il réduit à 16 lignes (sur des données fausses)

SELECT p.pName, p.pCode, MIN(p.pPrice) AS MinPrice 
    , SUM(s.Quantity) AS SalesQty, SUM(s.Quantity) * MIN(p.pPrice) AS SalesValue 
    , MIN(b.Quantity) AS BreakQty, MIN(b.Quantity) * MIN(p.pPrice) AS BreakValue 
    , MIN(r.Quantity) AS ReturnQty, MIN(r.Quantity) * MIN(p.pPrice) AS ReturnValue 
FROM Products AS p 

OUTER APPLY (SELECT SUM(s.Quantity) AS Quantity 
     FROM SalesLog AS s 
     WHERE s.BillDate = '12-10-2010' 
       AND s.ProductCode = p.pCode 
     ) AS s 
OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity 
     FROM SalesReturn AS r 
     WHERE r.BillDate = '12-10-2010' 
       AND r.ProductCode = p.pCode 
     ) AS r 
OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity 
     FROM Breakages AS b 
     WHERE b.BillDate = '12-10-2010' 
       AND b.ProductCode = p.pCode 
     ) AS b 
WHERE p.pGroup!=15 and p.pGroup!=16 
GROUP BY p.pName, p.pCode; 
+0

vous avez vraiment besoin de trouver un moyen d'écrire votre T-SQL d'une manière plus lisible, plus accessible! Ceci est juste un énorme, difficile à lire et difficile à comprendre désordre de caractères ...... –

+1

@marc_s: Parfois, je considère en laissant tel quel, et faire un commentaire sur le plus lisible la question est signifie qu'il est plus probable pour obtenir de l'aide ... –

Répondre

1

Vous déplacez les messages de but! Cependant, ci-dessous est une solution possible pour votre problème mis à jour.

Note:

  1. Il est beaucoup plus efficace d'utiliser> ou < au lieu de = si vous le pouvez!. C'est pourquoi j'ai changé le prédicat sur le p.pGroup. (Je suppose qu'il n'y a pas de groupes entre 15 et 16 ans).
  2. Toutes les mesures d'agrégation sont effectuées dans les sous-requêtes APPLY, vous n'avez donc plus besoin d'une clause GROUP BY.

Voici la requête mise à jour:

SELECT p.pName 
     , p.ProductCode 
     , p.Price AS MinPrice 
     , s.Quantity AS SalesQty 
     , s.Quantity * p.Price AS SalesValue 
     , b.Quantity AS BreakQty 
     , b.Quantity * p.Price AS BreakValue 
     , r.Quantity AS ReturnQty 
     , r.Quantity * p.Price AS ReturnValue 
FROM Products AS p 
OUTER APPLY (SELECT SUM(s.Quantity) AS Quantity 
      FROM SalesLog AS s 
      WHERE s.BillDate = '12-10 2010' 
        AND s.ProductCode = p.ProductCode 
      ) AS s 
OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity 
      FROM SalesReturn AS r 
      WHERE r.BillDate = '12-10 2010' 
        AND r.ProductCode = p.ProductCode 
      ) AS r 
OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity 
      FROM Breakages AS b 
      WHERE b.BillDate = '12-10 2010' 
        AND b.ProductCode = p.ProductCode 
      ) AS b 
WHERE p.pGroup < 15 
     AND p.pGroup > 16 
     AND (
      s.Quantity IS NOT NULL 
      OR r.Quantity IS NOT NULL 
      OR b.Quantity IS NOT NULL 
      ) 
+0

Aucun résultat ne s'affiche (0 ligne) –

+0

Salut Jon Payne J'ai trouvé une nouvelle façon d'atteindre mon objectif. J'ai créé une table temporaire où j'ajoute ces données, puis je supprime les lignes dont les valeurs sals, ruptures et valeurs de remboursement sont 0. –

+0

La requête ne fonctionnait pas parce que j'ai mis le BillDate mal? Je l'ai mis à '12 -10 2010' au lieu de '12 -10-2010 '? – JonPayne

1

Votre sous-requête, comme celui-ci, toujours obtenir les mêmes données pour chaque ligne parce que la clause where ne fait référence à rien de la requête externe.

isnull((select sum(Quantity) 
      from Breakages 
      where pGroup = 16 
        and quantity > 0), 0) as BreakQty 

Je n'ai pas le temps de deviner ce qu'elle devrait être.

+0

Correct - c'est la différence entre une sous-requête corrélée et non corrélée. Les résultats de sous-requêtes non corrélées ne changeront pas, quel que soit le nombre de lignes renvoyées. –

0

Les sous-requêtes doivent référencer la requête principale, avec une clause where. Associer la somme à SalesLog.ProductCode, je pense. Pour une réponse plus précise, vous devriez poster la structure des tables.

+0

il peut y avoir une condition quand il y a rupture de produit et pas de vente alors il ne montrera pas les ruptures. plus tôt j'avais la même référence au code SalesLog.Product. merci –

1

Il est difficile de donner une réponse précise car je ne connais pas vos données. Cependant, je pense que vous êtes après quelque chose comme:

SELECT s.pName 
     , s.ProductCode 
     , MIN(s.Price) AS MinPrice 
     , SUM(s.Quantity) AS SalesQty 
     , SUM(s.Quantity) * MIN(s.Price) AS SalesValue 
     , MIN(b.Quantity) AS BreakQty 
     , MIN(b.Quantity) * MIN(s.Price) AS BreakValue 
     , MIN(r.Quantity) AS ReturnQty 
     , MIN(r.Quantity) * MIN(s.Price) AS ReturnValue 
FROM SalesLog AS s 
OUTER APPLY (SELECT SUM(r.Quantity) AS Quantity 
      FROM @SalesReturn AS r 
      WHERE r.BillDate = s.BillDate 
        AND r.ProductCode = s.ProductCode 
      ) AS r 
OUTER APPLY (SELECT SUM(b.Quantity) AS Quantity 
      FROM @Breakages AS b 
      WHERE b.BillDate = s.BillDate 
        AND b.ProductCode = s.ProductCode 
      ) AS b 
WHERE s.BillDate = '12-10 2010' 
GROUP BY s.pName 
     , s.ProductCode ; 
+0

bonjour Jon Payne, j'ai mis à jour ma question en fonction de la situation actuelle avec requête. votre requête n'a montré aucune sortie donc j'ai ajouté la référence de la table Products et maintenant montrant les détails de tous les produits. Ce que je veux maintenant montrer seulement les produits où des ventes ou des ruptures ou des remboursements se sont produits. par exemple A a 10 ventes 0 break 0 remboursement -> il affichera B a 0 ventes 10 break 0 remboursement -> il affiche C a 0 ventes 0 break 0 remboursement -> il ne sera pas montrer grâce –

+0

Vous n'a pas mentionné une table de produits - j'allais sur les informations que vous avez fournies. – JonPayne

Questions connexes