Табличные переменные с псевдонимом в инструкции Delete From

Я хочу удалить строки из переменной таблицы SQL Server 2000/2005 на основе наличия других строк в той же таблице (удалить все строки с нулевым числом, если существует строка с числом, отличным от 0, с той же датой). Вот упрощенный пример, который должен удалить только строку, добавленную первой:

declare @O table (
    Month datetime,
    ACount int NULL
)

insert into @O values ('2009-01-01', 0)
insert into @O values ('2009-01-01', 1)
insert into @O values ('2008-01-01', 1)
insert into @O values ('2007-01-01', 0)

delete from @O o1
where ACount = 0
  and exists (select Month from @O o2 where o1.Month = o2.Month and o2.ACount > 0)

Проблема в том, что я не могу заставить SQL-сервер принять псевдоним o1 переменной таблицы (и я думаю, что псевдоним требуется из-за совпадающих имен полей o1.Month = o2.Month). Ошибка:

Сообщение 102, уровень 15, состояние 1, строка 11

Неверный синтаксис рядом с 'o1'.


person Anagoge    schedule 28.02.2009    source источник


Ответы (2)


Укажите псевдоним перед оператором FROM. Это означает, что вы удаляете из таблицы псевдонимов.

delete o1
from   @O as o1
where  ACount = 0 
       and exists ( select  Month 
                    from    @O o2 
                    where   o1.Month = o2.Month 
                            and o2.ACount > 0)


Результат

alt text

person dance2die    schedule 28.02.2009
comment
Вау, не знал об этом синтаксисе! Если бы вы не вставили изображение, я бы отклонил его как недействительное. Это работает на SQL2000 или только на SQL Server 2005? Я сейчас дома, поэтому не могу проверить напрямую. - person Joe Pineda; 28.02.2009
comment
Он должен работать на SQL 2k/2k5/2k8 (на скриншоте тестировалось на 2k8) - никогда не имел дело с SQL 7, поэтому не уверен насчет 7 - person dance2die; 28.02.2009

Попробуйте это, это должно сработать (первый FROM необязателен):

DELETE [FROM] @O
FROM @O o1
where ACount = 0
and exists (select Month from @O o2
      where o1.Month = o2.Month and o2.ACount > 0)

Обоснование: УДАЛИТЬ, как описано в здесь сначала ожидает таблицу без псевдонимов, ей может предшествовать необязательный FROM. После этого вы можете поставить псевдоним на таблицу во втором FROM, если вам нужно сделать JOIN, подзапрос и т.д.

person Joe Pineda    schedule 28.02.2009