2010-02-23 232 views
0

我正在使用MySQL。这里是我的架构:SQL:在FROM子句中有两次表

供应商(SID:整数,SNAME:字符串,地址字符串)

零件(PID:整数,PNAME:字符串,颜色:字符串)

目录( SID:整数,PID:整数,成本:实数)

(主键以粗体显示)

我吨rying编写选择sid S的对,提供相同部分的查询:

-- 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): Unknown column 's1.sid' in 'on clause'

我在做什么错?

回答

0

找到具有tw o或多个供应商:

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

找到这些部件的供应商(S),更面向未来的,可以呈现出两个以上的供应商:

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 
如果你想只有两家供应商在两列显示

..我想得... :-)

[更新]

什么,我想起来:

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 
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

+0

@wwosik:我也是,但与'或'它更可能他们可能是可选的。 –

+0

如果我理解得很好,OP希望成对供应商提供东西X.他不希望仅由一个供应商提供的产品或不提供的产品。这就是为什么我删除我的评论... – user76035

+0

@wwosik:我增加了更多的信息,但原来。查询将加入同一列 - 值将重复。 –

1

您正在加入s2和目录。该条款中不存在s1。

+0

如果是这样的话,你将无法加入's2'别名。 –

+0

@OMG小马:怎么这样? – brian

+0

两者都在同一条语句的同一行上声明。 –

0

我想你需要明确加入所有的表,如果你将使用显式连接。

例如

-- 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 
1

我不明白的错误消息,但:

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

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 

虽然因为所有你要求的是小岛屿发展中国家,也可以是简单的:

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

你的第一个例子实际上是一个内部连接,只是一个隐藏的连接(或者更确切地说是树)。 – user76035

+0

但是,然后返回的唯一行具有's1.sid = s2.sid = c1.sid = c2.sid' ...我怀疑'供应商'的'双',他希望有不同的'sid'键。 –

+0

@Joe,你有一个好点,虽然你不正确。目录表之间的连接不在'sid'上;它在'pid'上。好的一点是,我们应该排除对相同的目录;我会解决这个问题。谢谢。 –

0

你需要加入目录与自身

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

<条件为了避免对(A与B相同的X供应,所以B供应与A相同的X)