SQL:在FROM子句中有两次表

时间:2010-02-23 22:50:59

标签: mysql sql join mysql-error-1054

我正在使用MySQL。这是我的架构:

供应商( sid:整数,sname:字符串,地址字符串)

零件( pid:整数,pname:string,color:string)

目录( sid:整数,pid:整数,成本:真实)

(主键以粗体显示)

我正在尝试编写一个查询,选择提供相同部分的sid对:

-- Find pairs of SIDs that both supply the same part
SELECT s1.sid, s2.sid
FROM Suppliers AS s1, Suppliers AS s2
JOIN Catalog ON s1.sid = Catalog.sid OR s2.sid = Catalog.sid;

MySQL给了我这个错误:

  

ERROR 1054(42S22):未知列   's1.sid'在'on clause'

我做错了什么?

6 个答案:

答案 0 :(得分:1)

您正在混合ANSI-89和ANSI-92 JOIN语法 - 您只能使用一个或另一个。 ANSI-92:

   SELECT s1.sid, s2.sid
     FROM CATALOG c
LEFT JOIN SUPPLIERS s1 ON s1.sid = c.sid
LEFT JOIN SUPPLIERS s2 ON s2.sid = c.sid

如果要查看与两个供应商相关联的类别,请忽略LEFT关键字。

ANSI-89语法包含在FROM子句中声明的所有表,连接在WHERE子句中。

使用ANSI-92 - see this question for details

答案 1 :(得分:1)

您正在加入s2和目录。 s1在该子句中不存在。

答案 2 :(得分:1)

我不明白错误信息,但是:

在这种情况下我会避免使用join。试试这个

SELECT s1.sid, s2.sid
FROM suppliers s1,
     suppliers s2,
     catalog   c1,
     catalog   c2
WHERE c1.pid = c2.pid
AND   s1.sid = c1.sid
AND   s2.sid = c2.sid
AND   s1.sid < s2.sid

虽然你所要求的只是sids,但它可以更简单:

SELECT c1.sid, c2.sid
FROM catalog   c1,
     catalog   c2
WHERE c1.pid = c2.pid
AND   c1.sid < c2.sid

答案 3 :(得分:0)

如果您将使用显式连接,我认为您需要显式连接所有表。

e.g。

-- Find pairs of SIDs that both supply the same part
SELECT 
  s1.sid, 
  s2.sid
FROM 
  Catalog 

    LEFT OUTER JOIN 
  Suppliers AS s1,
    ON Catalog.sid = s1.sid

    LEFT OUTER JOIN
  Suppliers AS s2
    ON Catalog.sid = s2.sid 

答案 4 :(得分:0)

您需要自己加入目录

SELECT 
    pid, 
    c1.sid, 
    c2.sid
FROM Catalog c1
JOIN Catalog c2 ON c1.pid = c2.pid AND c1.sid < c2.sid

&LT;条件是避免成对(A提供与B相同的X,因此B提供与A相同的X)

答案 5 :(得分:0)

找到两个或更多供应商的零件:

select part_id
from catalog 
group by part_id
having count(part_id) >= 2

找到这些零件的供应商,更具前瞻性,可以展示两个或更多供应商:

select c.part_id, s.supplier_name 
from catalog c
join supplier s
where c.part_id in (
    select part_id
    from catalog 
    group by part_id
    having count(part_id) >= 2)
order by c.part_id, s.supplier_name

但如果你想要的零件只有两个供应商:

select c.part_id, group_concat(s.supplier_name) as suppliers 
from catalog c
join supplier s using(supplier_id)
where part_id in (
    select part_id
    from catalog 
    group by part_id
    having count(part_id) = 2)
group by c.part_id

如果你只想让这两个供应商在两栏中展示......我也在考虑......: - )

[UPDATE]

我的想法:

select c.part_id, c.min(c.supplier_id) as first, c.max(c.supplier_id) as second 
from catalog c
join supplier s
where c.part_id in (
    select part_id
    from catalog 
    group by part_id
    having count(part_id) = 2)
group by c.part_id
order by c.part_id

获取供应商名称:

select x.part_id, a.supplier_name, b.supplier_name from
(
    select c.part_id, c.min(c.supplier_id) as first, c.max(c.supplier_id) as second 
    from catalog c
    join supplier s
    where c.part_id in (
        select part_id
        from catalog 
        group by part_id
        having count(part_id) = 2)
    group by c.part_id
    order by c.part_id
 ) as x
 join supplier a on x.first = a.sid
 join supplier b on x.second = b.sid