Search code examples
mysqlsqljoinmysql-error-1054

SQL: Having a table twice in the FROM clause


I am using MySQL. Here is my schema:

Suppliers(sid: integer, sname: string, address string)

Parts(pid: integer, pname: string, color: string)

Catalog(sid: integer, pid: integer, cost: real)

(primary keys are bolded)

I am trying to write a query that selects pairs of sids that supply the same part:

-- 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 gives me this error:

ERROR 1054 (42S22): Unknown column 's1.sid' in 'on clause'

What am I doing wrong?


Solution

  • find parts with two or more suppliers:

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

    find the supplier(s) of those parts, more future-proof, can show two or more suppliers:

    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
    

    but if you want parts which exactly has two suppliers only:

    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
    

    if you want only those two suppliers to display in two columns.. me thinking too... :-)

    [UPDATE]

    what i thought up:

    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
    

    to get the supplier names:

    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