2013-06-20 3 views
2

Я столкнулся с любопытной ошибкой SQL. Последний запрос не работает. Конечно, я могу просто разделить этот DELETE на три запроса, но мне действительно интересно, почему MySQL не позволяет мне так поступать.MySQL DELETE FROM с подзапросом UNION по условию IN

Небольшой пример:

(SELECT id FROM stairs WHERE building = 123) 
UNION 
(SELECT id FROM lift WHERE building = 123) 
UNION 
(SELECT id FROM qrcodeid WHERE building = 123) 

работает!

DELETE FROM startpoint WHERE id IN (SELECT id FROM stairs WHERE building = 123) 

работ, тоже!

В то время как

DELETE FROM startpoint WHERE id IN (
    (SELECT id FROM stairs WHERE building = 123) 
    UNION 
    (SELECT id FROM lift WHERE building = 123) 
    UNION 
    (SELECT id FROM qrcodeid WHERE building = 123) 
) 

вызывает ошибку

# 1064 - У Вас есть ошибка в вашем SQL синтаксиса; проверьте руководство, которое соответствует версии сервера MySQL для правильного синтаксиса, чтобы использовать рядом с 'UNION (SELECT ID FROM подъемником WHERE здание = 123) UNION (SELECT ID FROM QRC' в строке 3

Anyone ключ?

ответ

1

Попробуйте что SQL

DELETE FROM startpoint WHERE id IN (
SELECT id FROM stairs WHERE building = 123 
UNION 
SELECT id FROM lift WHERE building = 123 
UNION 
SELECT id FROM qrcodeid WHERE building = 123) 
+0

Спасибо, это работает ... И что не так с моими скобками? –

+1

Здесь ваш [ответ] (http://www.w3schools.com/sql/sql_union.asp);) – rkpasia

+1

Как вы можете видеть, нет скобок! – rkpasia

2

Попробуйте эту версию вместо:.

DELETE FROM startpoint 
    WHERE id IN (select * 
       from ((SELECT id FROM stairs WHERE building = 123) 
         UNION 
         (SELECT id FROM lift WHERE building = 123) 
         UNION 
         (SELECT id FROM qrcodeid WHERE building = 123) 
       ) 

Я думаю, этот вопрос является аркан проблема с определением подзапроса подзапрос является select заявление, в то время как union является конъюнкцией select заявлений

.

EDIT:

Фактически, если вы хотите повысить эффективность, вы не использовали бы этот подход вообще. Я просто пытался показать, как исправить ошибку. Лучшим решением было бы:

DELETE sp FROM startpoint sp 
    WHERE EXISTS (select 1 from stairs s where s.building = 123 and s.id = sp.id) or 
      EXISTS (select 1 from lift l where l.building = 123 and l.id = sp.id) or 
      EXISTS (select 1 from qrcodeid q where q.building = 123 and q.id = sp.id); 

Индексы рекомендуется на stairs(id, building), lift(id, building) и qrcodeid(id, building).

+0

Это работает (когда SQL ошибка исправляется - смотрите мое редактирование). Это не так эффективно, как решение rkpasia, но оно работает для случаев, когда требуются скобки для членов профсоюза, например, если LIMIT используется для дочерних запросов. –