2010-02-23 236 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)