Reputation: 2348
I am trying to find the makers of two or more different computers (PC and/or laptop) with "HD" to be greater than or equal to 10.
Product has: maker & model
both PC & Laptop have: model & HD
This is what I have written so far:
SELECT DISTINCT maker
FROM
(
(
SELECT model, maker
FROM
(SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
) as ta
UNION ALL
(
SELECT model, maker
FROM
(SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
) AS tb
) AS t1
JOIN t1 as t2
ON (t1.model != t2.model and t1.model > t2.model)
However, it provides me with lovely error:
1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS tb ) AS t1 JOIN t1 as t2 ON (t1.model != t2.model and t1.model > t2.model)' at line 16
Working pieces:
SELECT model, maker
FROM
(SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
SELECT model, maker
FROM
(SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
Upvotes: 1
Views: 682
Reputation: 753735
Since your parentheses are balanced, I don't think 'too many parentheses' is the problem.
The trouble is at
JOIN t1 AS t2
You have t1
as the UNION query; you can't readily also have t1
as a table without confusing everyone.
You might be able to write:
JOIN t3 AS t2
where t3
is a table (or view) in the DBMS.
Incidentally, your ON condition doesn't need both conditions:
ON (t1.model != t2.model AND t1.model > t2.model)
It is sufficient to use:
ON (t1.model > t2.model)
If you want to do a self-join on the UNION, you will have to write the UNION out twice, or (if MySQL supported it, which I don't think it does) a CTE (common table expression), aka WITH clause before the main SQL statement:
WITH t1(model, maker) AS
(SELECT model, maker
FROM (SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
UNION ALL
SELECT model, maker
FROM (SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
)
SELECT DISTINCT t1a.maker
FROM t1 AS t1a
JOIN t1 AS t1b ON (t1a.model > t1b.model)
I'm not quite sure what the ON condition means; it seems to favour the Zebras over the Aardvarks, but that's about all. However, that is syntactically (approximately) correct.
Without the WITH clause, you write the expression out twice:
SELECT DISTINCT t1a.maker
FROM (SELECT model, maker
FROM (SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
UNION ALL
SELECT model, maker
FROM (SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
) AS t1a
JOIN (SELECT model, maker
FROM (SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
UNION ALL
SELECT model, maker
FROM (SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
) AS t1b
ON (t1a.model > t1b.model)
Of course, this was just an interpretation of your query. Your question seems much simpler:
SELECT Maker
FROM (SELECT model, maker
FROM (SELECT model FROM laptop WHERE hd >= 10) AS lap2
NATURAL JOIN product
UNION ALL
SELECT model, maker
FROM (SELECT model FROM pc WHERE hd >= 10) AS pc2
NATURAL JOIN product
) AS t -- per comment (and SQL standard, but it really is superfluous!)
GROUP BY Maker
HAVING COUNT(*) > 1;
Upvotes: 3