2017-02-24 101 views
1

我需要找到每个零件的价格最低的供应商。SQL查询找到每个零件的最低价格的供应商

表:供应商(SID,SNAME,地址),零部件(PID,PNAME,颜色),目录(SID,PID,成本)

这工作:

SELECT 
    sname, pid 
FROM 
    (SELECT 
     * 
    FROM 
     suppliers 
    NATURAL JOIN catalog 
    NATURAL JOIN (SELECT 
     pid, MIN(cost) AS min_cost 
    FROM 
     catalog 
    GROUP BY (pid)) AS m 
    HAVING cost = min_cost) AS n 

但是当我尝试它缩短到下面我得到一个错误,有在having子句中的未知成本:

SELECT 
    sname, pid 
FROM 
    suppliers 
     NATURAL JOIN 
    catalog 
     NATURAL JOIN 
    (SELECT 
     pid, MIN(cost) AS min_cost 
    FROM 
     catalog 
    GROUP BY (pid)) AS m 
HAVING cost = min_cost 

为什么不能找到它的成本?因为我已经加入子查询来编目,所以不是表中的成本?

编辑

我改成了使用INNER JOIN代替NATURAL JOIN按照建议,但我仍然得到同样的错误。新查询:

SELECT 
    s.sname, m.pid 
FROM 
    suppliers s 
     INNER JOIN 
    catalog c ON s.sid = c.sid 
     INNER JOIN 
    (SELECT 
     pid, MIN(cost) AS min_cost 
    FROM 
     catalog 
    GROUP BY (pid)) AS m ON c.pid = m.pid 
HAVING cost = min_cost 

EDIT_2

问题是不是JOINHAVING,这实际上应该是WHERE,如图bbrumm的回答。

+2

只要忘记'NATURAL JOIN'。这是一个等待发生的错误(或者在这种情况下实际发生)。使用'ON'或'USING'子句。 –

+0

@GordonLinoff解释了为什么我没有在任何SO答案中看到它。为什么我们在使用Access数据库时总是在我的VBA课程中使用'ON'。不过,现在我正处于初学者RDBMS课程和我们的教授。已经告诉我们尽可能使用'NATURAL JOIN' ...很高兴知道未来,尽管 –

+1

听起来像一个教授。不想回答问题。 – Hogan

回答

3

我建议这样的查询:

SELECT 
supplier.sname, 
catalog.pid 
FROM suppliers 
INNER JOIN catalog ON suppliers.supplier_id = catalog.supplier_id 
INNER JOIN 
    (SELECT 
    pid, MIN(cost) AS min_cost 
    FROM catalog 
    GROUP BY (pid)) AS m 
ON catalog.pid = m.pid 
WHERE catalog.cost = m.min_cost; 

我对列名做出一些假设(例如supplier_id),您可能需要改变。可以指出,“cost = min_cost”是JOIN的一部分,所以它也可以去那里。我也没有将表别名作为最佳实践,但这不是必需的。

+0

我刚刚更新了我的问题,并且与您的查询具有相同的查询,我只需将'HAVING'更改为'WHERE'。谢谢。 –

+0

没问题。仅供参考 - HAVING执行与WHERE类似的功能,但通常与GROUP BY子句一起使用,因为它在幕后的不同位置运行。 – bbrumm

相关问题