2011-04-29 3 views
1

J'essaie d'interroger quelques tables dans notre base de données qui contient des données produit. C'est une base de données MSSQL 2005. Le problème est qu'il retourne plusieurs lignes pour un produit lorsque j'en ai besoin pour produire une seule ligne par produit. Blow est la requête et les résultats que j'utilise.sélectionner un résultat de la requête

SELECT  ProductItem.sku, ProductItem.title, ProductItem.short_desc, ProductItem.long_desc, ProductItem.active, ProductItem.product_item_id, 
        ProductCategory.category_desc, ProductCategoryMap.product_id, ProductCategory.active AS activecat, Product.adwords_label, 
        ProductItem.item_price, ProductItem.sale_price 
FROM   Product INNER JOIN 
         ProductCategoryMap INNER JOIN 
         ProductCategory ON ProductCategoryMap.product_category_id = ProductCategory.product_category_id ON 
         Product.product_id = ProductCategoryMap.product_id FULL OUTER JOIN 
         ProductItem ON Product.product_key = ProductItem.sku 
WHERE  (ProductItem.active = 1) AND (ProductCategory.active = 1) 

Cela renvoie les résultats suivants: enter image description here

Je sais que le problème se produit parce que le produit réside dans plusieurs catégories, mais vraiment je ne ai pas besoin dans toutes les catégories de son, juste un d'entre eux. Donc, idéalement, un seul produit pour chaque ligne retournée

Je n'arrive pas à comprendre comment faire pour que ma requête atteigne cet objectif.

Quelqu'un peut-il m'aider s'il vous plaît?

+0

S'il existe plusieurs catégories pour un produit et que vous sélectionnez la catégorie category dans la liste de sélection. Quelle catégorie voulez-vous afficher ou vous vous fichez de celle qui est affichée? – Chandu

+0

Pour ce projet, peu importe lequel est affiché. – tking

+0

Ma réponse est la plus similaire à KM – SQLMason

Répondre

2

À première vue, supprimez les colonnes de catégories et ajoutez DISTINCT. Vous avez demandé "catégorie" afin que vous puissiez obtenir toutes les catégories.

aussi:

  • WHERE change votre FULL OUTER JOIN pour un INNER
  • get product_id du produit
  • la colonne activecat est sous-entendu par la clause where de toute façon

Je Je l'ai modifié pour plus de clarté et ajouté un agrégat pour obtenir une catégorie

SELECT 
    PI.sku, PI.title, PI.short_desc, PI.long_desc, 
    PI.active, PI.product_item_id, 
    PI.item_price, PI.sale_price, 

    MIN(PC.category_desc), 
    P.product_id, 
    1 AS activecat, --implied by filter 

    P.adwords_label 
FROM 
    ProductItem PI 
    INNER JOIN 
    Product P ON P.product_key = PI.sku 
    INNER JOIN 
    ProductCategoryMap PCM ON P.product_id = PCM.product_id 
    INNER JOIN 
    ProductCategory PC ON PCM.product_category_id = PC.product_category_id 
WHERE 
    (PI.active = 1) AND (PC.active = 1) 
GROUP BY 
    PI.sku, PI.title, PI.short_desc, PI.long_desc, 
    PI.active, PI.product_item_id, 
    PI.item_price, PI.sale_price, 
    P.product_id, 
    P.adwords_label 

Edit: vous pouvez ranger plus avec qui POSTULER traitera également pas catégories si changé OUTER APPLY

SELECT 
    PI.sku, PI.title, PI.short_desc, PI.long_desc, 
    PI.active, PI.product_item_id, 
    PI.item_price, PI.sale_price, 

    PC2.category_desc, 
    P.product_id, 
    PC2.active AS activecat, 

    P.adwords_label 
FROM 
    ProductItem PI 
    INNER JOIN 
    Product P ON P.product_key = PI.sku 
    CROSS APPLY 
    (
    SELECT TOP 1 
     PC.category_desc, PC.active 
    FROM 
     ProductCategoryMap PCM 
     INNER JOIN 
     ProductCategory PC ON PCM.product_category_id = PC.product_category_id 
    WHERE 
     P.product_id = PCM.product_id AND PC.active = 1 
    ORDER BY 
     PC.category_desc 
    ) PC2 
WHERE 
    PI.active = 1 
+0

Je comprends ce que vous dites et je le ferais ... MAIS j'ai besoin de saisir au moins une catégorie pour ce projet. – tking

+0

Génial, très bien travaillé. Je ne suis pas un gourou du sql et je n'aurais pas compris cela sans votre aide. Merci! – tking

2

La réponse dépend un peu de ce que vous voulez.

Si vous vous intéressez uniquement à la catégorie de produit pour demander "ce produit a-t-il au moins 1 catégorie active?" Votre recherche ressemblerait ...

SELECT  DISTINCT 
      ProductItem.sku, 
      ProductItem.title, 
      ProductItem.short_desc, 
      ProductItem.long_desc, 
      ProductItem.active, 
      ProductItem.product_item_id, 
      ProductCategoryMap.product_id, 
      Product.adwords_label, 
      ProductItem.item_price, 
      ProductItem.sale_price 
FROM  
      Product 
INNER JOIN ProductCategoryMap ON Product.product_id = ProductCategoryMap.product_id 
INNER JOIN ProductCategory  ON ProductCategoryMap.product_category_id = ProductCategory.product_category_id 
FULL JOIN ProductItem   ON Product.product_key = ProductItem.sku 
WHERE  
      (ProductItem.active = 1) AND 
      (ProductCategory.active = 1) 

Si vous ne se soucient pas de la catégorie du tout ça ressemblerait ....

SELECT  
      ProductItem.sku, 
      ProductItem.title, 
      ProductItem.short_desc, 
      ProductItem.long_desc, 
      ProductItem.active, 
      ProductItem.product_item_id, 
      ProductCategoryMap.product_id, 
      Product.adwords_label, 
      ProductItem.item_price, 
      ProductItem.sale_price 
FROM  
      Product 
INNER JOIN ProductCategoryMap ON Product.product_id = ProductCategoryMap.product_id 
ProductCategory.product_category_id 
FULL JOIN ProductItem   ON Product.product_key = ProductItem.sku 
WHERE  
      (ProductItem.active = 1) 

Si vous voulez inclure les noms de catégorie active comme liste CSV (esprit juste le plan d'exécution si cela est un grand jeu de résultats) ....

SELECT  ProductItem.sku, 
      ProductItem.title, 
      ProductItem.short_desc, 
      ProductItem.long_desc, 
      ProductItem.active, 
      ProductItem.product_item_id, 
      ProductCategory.category_desc, 
      ProductCategoryMap.product_id, 
      ProductCategory.active AS activecat, 
      Product.adwords_label, 
      ProductItem.item_price, 
      ProductItem.sale_price, 
      (SELECT substring((SELECT (', ' + CAST(PC.category_desc AS varchar(50))) 
           FROM ProductCategory PC 
           WHERE PC.product_category_id = ProductCategoryMap.product_category_id AND 
             PC.active = 1 
           FOR XML PATH('') 
          ), 3, 8000) 
        )  AS ProductCategoriesCSV 
FROM  
      Product 
INNER JOIN ProductCategoryMap ON Product.product_id = ProductCategoryMap.product_id 
INNER JOIN ProductCategory  ON ProductCategoryMap.product_category_id = ProductCategory.product_category_id 
FULL JOIN ProductItem   ON Product.product_key = ProductItem.sku 
WHERE  
      (ProductItem.active = 1) 

HTH, -Eric

1

Essayer ...

SELECT  
    I.sku, 
    I.title, 
    I.short_desc, 
    I.long_desc, 
    I.active, 
    I.product_item_id, 
    T.category_desc, 
    P.product_id, 
    T.active AS activecat, 
    P.adwords_label, 
    I.item_price, 
    I.sale_price 
FROM   
    Product P 

    CROSS APPLY 
    (
    SELECT TOP 1 
     C.category_desc, 
     C.active AS activecat 
    FROM 
     ProductCategoryMap CM 

     INNER JOIN ProductCategory C 
     ON CM.product_category_id = C.product_category_id 
    WHERE 
     P.product_id = CM.product_id 
     AND 
    (C.active = 1) 
) T 

    FULL OUTER JOIN ProductItem I 
    ON P.product_key = I.sku 
WHERE 
(I.active = 1) 
Questions connexes