выберите по одному результату из запроса - PullRequest
1 голос
/ 29 апреля 2011

Я пытаюсь запросить несколько таблиц в нашей базе данных, которая содержит данные о продукте.Это база данных MSSQL 2005.Проблема состоит в том, что он возвращает несколько строк для одного продукта, когда мне нужно произвести только одну строку для каждого продукта.Blow - это запрос и результаты, которые я использую.

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)

Это возвращает следующие результаты: enter image description here

Я знаю, что проблема возникает, потому что продукт находится в нескольких категориях, но на самом делеМне не нужна каждая категория, только одна из них.Поэтому в идеале возвращается только один продукт для каждой строки

Я не могу понять, как сделать так, чтобы мой запрос достиг этого.

Кто-нибудь может мне помочь, пожалуйста?

Ответы [ 3 ]

2 голосов
/ 29 апреля 2011

Ответ немного зависит от того, что вы хотите.

Если вас интересует только категория продукта с вопросом "есть ли у этого продукта хотя бы одна активная категория?"Ваш запрос будет выглядеть следующим образом ...

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)

Если вам не нужна категория, он будет выглядеть следующим образом ...

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) 

Если вы хотите включить activeимена категорий в виде списка CSV (просто обратите внимание на план выполнения, если это большой набор результатов) ....

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

2 голосов
/ 29 апреля 2011

На первый взгляд, уберите столбцы категорий и добавьте DISTINCT.Вы запросили «категорию», чтобы вы могли получить все категории.

Также:

  • ГДЕ изменяет ваше ПОЛНОЕ НАСТРОЙСТВО НА ВНУТРЕННЕЕ
  • get product_idиз продукта
  • столбец activecat в любом случае подразумевается предложением where

Я настроил его для ясности и добавил агрегат, чтобы получить одну категорию

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

Изменить: вы можете привести в порядок больше с APPLY, который также будет иметь дело с нет категорий, если изменить на 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
1 голос
/ 29 апреля 2011

Попробуйте ...

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) 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...