从三个表之间的1到多个关系中检索一行

时间:2010-07-19 05:14:02

标签: sql subquery aggregate relationship

我有以下三个表:

---- ----产品

PRODUCT_ID     DESC     
1              'Pencil'   
2              'Paper'

---- ---- PRICE_BY_SUPPLIER

PRODUCT_ID     SUPPLIER_ID     PRICE  
1              1               10  
1              2               9  
1              3               9.5  
2              1               5

---- ---- IMAGES_BY_PRODUCT

PRODUCT_ID     NAME  
1              'pencil.img'  
1              'pen.img'  
1              'pencil_other.img'  
2              'paper.img'

我想要一个查询来提取最低价格,持有产品的供应商数量和一个图像(所有供应商中的一个图像)。输出查询应如下所示:

---- ---- FINAL_QUERY

PRODUCT_ID     MIN_PRICE     IMAGE          SUPPLIER_COUNT  
1              9             'pencil.img'   3  
2              5             'paper.img'    1

我有这个查询返回除图像之外的所有内容。

SELECT f.PRODUCT_ID, f.DESC, x.MIN_PRICE, x.SUPPLIER_COUNT  
  FROM (
        SELECT pp.PRODUCT_ID, 
               MIN(pp.PRICE) AS MIN_PRICE, 
               COUNT(pp.PRODUCT_ID) AS SUPPLIER_COUNT 
          FROM PRICE_BY_SUPPLIER AS pp 
         GROUP 
            BY pp.PRODUCT_ID
       )   
       AS x
       INNER JOIN PRODUCT AS f 
         ON f.PRODUCT_ID = X.PRODUCT_ID

你能帮我完成我的查询吗?

3 个答案:

答案 0 :(得分:0)

您可以添加另一个联接来获取图像。例如,每个productid的max图像:

SELECT  f.PRODUCT_ID, f.DESC, x.MIN_PRICE, x.SUPPLIER_COUNT, img.Name
FROM    ( 
        select  pp.PRODUCT_ID
        ,       MIN(pp.PRICE) as MIN_PRICE
        ,       COUNT(pp.PRODUCT_ID) as SUPPLIER_COUNT 
        from    PRICE_BY_SUPPLIER as pp 
        group by 
                pp.PRODUCT_ID
        ) AS x 
JOIN    PRODUCT as f 
on      f.PRODUCT_ID = X.PRODUCT_ID
JOIN    (
        select  max(name)
        from    images_by_product
        group by
                product_id
        ) as img
on      img.PRODUCT_ID = X.PRODUCT_ID

如果图片是可选的,请将join替换为outer join。根据您的DBMS,您还可以获取随机图像。例如,在SQL Server中,您可以将联接替换为cross apply

...
on      f.PRODUCT_ID = X.PRODUCT_ID
CROSS APPLY
        (
        select  top 1 name
        from    images_by_product
        where   PRODUCT_ID = X.PRODUCT_ID
        order by
                newid()
        ) as img

甚至直接在select子句中:

SELECT  f.PRODUCT_ID, f.DESC, x.MIN_PRICE, x.SUPPLIER_COUNT, img.Name
,       (
        select  top 1 name
        from    images_by_product
        where   PRODUCT_ID = X.PRODUCT_ID
        order by
                newid()
        ) as img
FROM    ( 
        select  pp.PRODUCT_ID
...

答案 1 :(得分:0)

试试这个:

SELECT DISTINCT p.product_id, MIN(pbs.price), ibp.name, pbs.supplier_id
FROM product p
INNER JOIN price_by_supplier pbs
ON  p.product_id = pbs.product_id
INNER JOIN images_by_product ibp
ON p.product_id = ibp.product_id
GROUP BY p.product_id

我能够得到您的确切输出(除了supplier_count,因为这对我没有意义。如果可以,请进一步解释。

PRODUCT_ID     MIN_PRICE     IMAGE          SUPPLIER_ID  
1              9             'pencil.img'   1  
2              5             'paper.img'    1

<强>更新:

这是获得你想要的东西的一种蹩脚方式,但......它确实有效:

SELECT DISTINCT p.product_id, MIN(pbs.price), ibp.name, COUNT(pbs.supplier_id)
FROM product p
INNER JOIN images_by_product ibp
ON p.product_id = ibp.product_id
INNER JOIN price_by_supplier pbs
ON  p.product_id = pbs.product_id
GROUP BY  pbs.price
LIMIT 2


PRODUCT_ID     MIN_PRICE     IMAGE          SUPPLIER_ID  
2              5             'paper.img'     1  
1              9             'pencil.img'    3

答案 2 :(得分:0)

而不是参与所有那些可怕的联接,你不能尝试类似......

SELECT PRODUCT_ID,
       (SELECT MIN(PRICE)
             FROM PRICE_BY_SUPPLIER
             WHERE PRICE_BY_SUPPLIER.PRODUCT_ID = PRODUCT.PRODUCT_ID) AS MIN_PRICE,
       (SELECT NAME
             FROM PRODUCT_IMAGES
             WHERE PRODUCT_IMAGES.PRODUCT_ID = PRODUCT.PRODUCT_ID
             LIMIT 1) AS PRODUCT_IMAGES,
       (SELECT COUNT(*)
             FROM PRICE_BY_SUPPLIER
             WHERE PRICE_BY_SUPPLIER.PRODUCT_ID = PRODUCT.PRODUCT_ID) AS SUPPLIER_COUNT
    FROM PRODUCT_ID;