2010-02-20 4 views
6

Это мой запрос:SQL: Синтаксическая ошибка с пересечением?

-- Sids of suppliers who supply a green part AND a red part 
(SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
JOIN Parts ON Parts.pid = Catalog.pid 
WHERE Parts.color = "red") 
INTERSECT 
(SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
JOIN Parts ON Parts.pid = Catalog.pid 
WHERE Parts.color = "green"); 

Это ошибка:

ERROR 1064 (42000): 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 "INTERSECT (SELECT Suppliers.sid FROM Suppliers JOIN Catalog ON Catalog.sid = Sup" on line 6.

Что я делаю неправильно?

Это схема:

Поставщики (SID: целочисленные, SNAME: строка, строка адреса)

части (PID: целочисленные, PNAME: строка, цвет: строка)

Каталог (с.и.д.: целое число, Pid: целое, стоимость: реальная)

полужирный = первичный ключ

ответ

6

MySQL, который вы, по всей видимости, использует, не поддерживает синтаксис INTERSECT. Вам придется решить его по-другому.

В этом случае это тривиально - нам нужен только список всех suppiers, которые предлагают «зеленый» и «красный» какой-либо части - ваш запрос не беспокоит, связаны ли сами части, поэтому мы можем решить довольно легко, как это:

SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
JOIN Parts ON Parts.pid = Catalog.pid 
WHERE Parts.color IN ('red', 'green') 
GROUP BY Suppliers.sid 
HAVING COUNT(DISTINCT Parts.color) = 2 

Лично я не считаю, что исходный запрос является типичной INTERSECT проблемы. Посмотрите на РЕГИСТРИРУЙТЕСЬ решение, предложенное Винко Vrsalovic для общего решения для эмуляции INTERSECT (который я бы предпочел кстати, даже если RDBMS бы на самом деле предложение INTERSECT нативно)

+0

Было бы интересно узнать, что быстрее, этот запрос или мой запрос - я думаю, что это происходит до того, что происходит быстрее, 2-го соединения или группы по операциям. – Hogan

+0

@Hogan, * shrug *. Это зависит от очень многих вещей: индексов, какого движка, сколько строк, сколько памяти. enless list ... Если бы вопрос заключался в том, чтобы найти самое быстрое решение, я бы принял совершенно иной подход к ответу на это. На данный момент я вхожу в режим: как переписать стандартный SQL, чтобы получить эквивалентный результат в случае, если MySQL не поддерживает синтаксис. –

+0

точка взята, я думаю, что я всегда в режиме того, что является самым быстрым, а не самым ясным. – Hogan

2

Это должно делать то, что вы хотите:

SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
INNER JOIN Parts AS parts1 ON parts1.pid = Catalog.pid AND parts1.color = "red" 
INNER JOIN Parts AS parts2 ON parts2.pid = Catalog.pid AND parts2.color = "green" 
+0

Я не думаю, что это проблема в этом случае. «INTERSECT» просто не поддерживается MySQL. –

+0

И этот запрос не сработает.OP хочет все сидики, где у них есть зеленая и красная часть. Ваш запрос возвращает все сиды с зеленой ИЛИ красной частью. –

+0

@Roland, @Vinko: Да, я видел это, я исправил ответ, это должно делать то, что он хочет, и быть быстрее, чем подзапрос. – Hogan

4

Ничего, MySQL не имеет ключевое слово INTERSECT , Вы можете переписать его как INNER JOIN:

SELECT DISTINCT sid FROM 
(SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
JOIN Parts ON Parts.pid = Catalog.pid 
WHERE Parts.color = "red") a 
INNER JOIN 
(SELECT Suppliers.sid 
FROM Suppliers 
JOIN Catalog ON Catalog.sid = Suppliers.sid 
JOIN Parts ON Parts.pid = Catalog.pid 
WHERE Parts.color = "green") b 
ON (a.sid = b.sid); 

Этот запрос может, конечно, быть лучше написано, но это, чтобы показать, что пересекаются, но только внутреннее соединение с выбора различны, вы можете автоматически преобразовать один в другой ,

+0

Я в основном согласен, но 'INTERSECT' не совсем то же самое, что' INNER JOIN'. 'INTERSECT' по умолчанию' INTERSECT DISTINCT', что означает, что требуется возвращать только уникальные строки. В практических случаях и, вероятно, в этом случае, это просто сработало бы, но чтобы получить истинную переписку, вам нужно добавить либо «DISTINCT», либо «GROUP BY» –

+0

@Roland: Спасибо за примечание, я отредактировал его, чтобы отразить его , –

+0

все прохладный. Теперь вы получаете +1, потому что я в основном думаю, что 'JOIN' намного, намного лучше, чем' INTERSECT' :) Только раз, когда я когда-либо видел пересекающиеся, в домашних домашних заданиях SQL;) –

0

Другим решением для того, чтобы использовать INTERSECT в MySQL является использование В пункте. Проблема: "Найти курс корочки курсов осенью 2009 года и весна 2010"

//DML sample 
(select course_id 
from section 
where semester = ‘Fall’ and year = ‘2009’) 
intersect 
(select course_id 
from section 
where semester = ‘Spring’ and year = ‘2010’); 

В MySQL:

select distinct course_id 
from section 
where semester = 'Fall' and year= 2009 and 
course_id in (select course_id 
from section 
where semester = 'Spring' and year= 2010); 

Если вам нужно больше В пункте, пожалуйста, поиск на Google ,

Смежные вопросы