3
votes

Comment exclure les mêmes lignes dans SELECT

J'ai ce script qui crée une table et stocke les informations de commande de vente. Le scénario sous-jacent est qu'une fois que l'article est ajouté à la commande de vente, son Statut est 'A' signifie Ajouter . Plus tard, le client souhaite que cet élément soit supprimé, nous ajoutons donc une nouvelle ligne avec les mêmes détails, mais Statut comme 'D' signifie Supprimer . Maintenant, je souhaite obtenir uniquement les articles de la commande de vente actifs qui ne doivent pas inclure cet article qui a été ajouté puis supprimé de la commande. Voici mon script.

SELECT ORDER_NUMBER, ITEM_NAME, QUANTITY, PRICE FROM [dbo].[SALE_DETAIL]
WHERE Status <> 'D'
GROUP BY ORDER_NUMBER, ITEM_NAME, QUANTITY, PRICE

La sortie attendue que je recherche devrait ressembler à quelque chose comme ça, car l'élément 'Sofa' a été annulé de la commande.

XXX

Requête:

ORDER_NUMBER    ITEM_NAME       QTY PRICE
SO-100-ORD-19   Dining Table    1   50000
SO-100-ORD-19   Double Bed      5   70000


3 commentaires

Qu'est-ce que tu as essayé jusque-là? Vous avez posé suffisamment de questions pour savoir que vous devriez également publier vos tentatives.


Cela ressemble à une conception maladroite des données - que se passe-t-il si quelqu'un insère un enregistrement D qui ne correspond pas dans tous les détails à un enregistrement A existant? (Soit dans son intégralité, soit simplement par exemple en fonction du prix)


Voir ma réponse mise à jour.


4 Réponses :


3
votes

J'utiliserais NOT EXISTS :

SELECT SD.ORDER_NUMBER,
       SD.ITEM_NAME,
       SD.QUANTITY,
       SD.PRICE
FROM dbo.[SALE_DETAIL] SD
WHERE NOT EXISTS (SELECT 1
                  FROM dbo.[SALE_DETAIL] e
                  WHERE e.ORDER_NUMBER = SD.ORDER_NUMBER
                    AND e.ITEM_NAME = SD.ITEM_NAME
                    AND e.[Status] = 'D');


0 commentaires

1
votes

En mots: sélectionnez tous les 'A' -records pour lesquels aucun 'D' -record correspondant n'existe.

En SQL:

SELECT ORDER_NUMBER, ITEM_NAME, QUANTITY, PRICE
FROM [dbo].[SALE_DETAIL] X
WHERE Status = 'A'
AND NOT EXISTS (
  SELECT 1
  FROM [dbo].[SALE_DETAIL] Y
  WHERE Y.Status       = 'D'
  AND   Y.ORDER_NUMBER = X.ORDER_NUMBER
  AND   Y.ITEM_NAME    = X.ITEM_NAME
)


0 commentaires

2
votes

Logiquement, la réponse basée sur les ensembles est d'utiliser SAUF :

declare @SALE_DETAIL table([ORDER_NUMBER] [varchar](50) NULL,
    [ITEM_NAME] [varchar](250) NULL,
    [QUANTITY] [int] NULL,[PRICE] [numeric](18, 0) NULL,[Status] [varchar](50) NULL)
INSERT @SALE_DETAIL ([ORDER_NUMBER], [ITEM_NAME], [QUANTITY], [PRICE], [Status]) VALUES
(N'SO-100-ORD-19', N'Double Bed', 5, CAST(70000 AS Numeric(18, 0)), N'A'),
(N'SO-100-ORD-19', N'Sofa', 5, CAST(10000 AS Numeric(18, 0)), N'A'),
(N'SO-100-ORD-19', N'Dining Table', 1, CAST(50000 AS Numeric(18, 0)), N'A'),
(N'SO-100-ORD-19', N'Sofa', 5, CAST(10000 AS Numeric(18, 0)), N'D')

select Order_number,Item_name,Quantity,Price
from @SALE_DETAIL
where Status = 'A'
except
select Order_number,Item_name,Quantity,Price
from @SALE_DETAIL
where Status = 'D'

Qui produit les résultats que vous 'ai demandé. Cependant, notez que pour une raison quelconque, cela semble souvent mal fonctionner dans la pratique, auquel cas quelque chose comme La réponse de Larnu peut être préféré.


0 commentaires

1
votes

Vous pouvez essayer d'obtenir le résultat attendu en utilisant l'opérateur not in comme indiqué ci-dessous.

ORDER_NUMBER    ITEM_NAME   QUANTITY    PRICE   Status
------------------------------------------------------
SO-100-ORD-19   Dining Table    1       50000   A       
SO-100-ORD-19   Double Bed      5       70000   A        

Le résultat est comme indiqué ci-dessous

SELECT DISTINCT A.ORDER_NUMBER, A.ITEM_NAME,A.QUANTITY, A.PRICE, A.Status
FROM SALE_DETAIL A
    where A.ITEM_NAME not in (select s.ITEM_NAME from SALE_DETAIL s
    where s.[Status] = 'D')


0 commentaires