На SQL сервере, у меня есть таблица MyTable со следующими 3 столбцами: P (bigint), F (bigint), D (bigint).
Теперь мне нужно сделать следующее: сгруппируйте все записи по одному значению P, затем в каждой группе вычислите следующее значение:
V = ABS((P & 0xFFFFFFFF) * 256 - F)
для каждой записи и удалите все записи в группе, за исключением записи с минимальным значением V.
Поэтому я пишу оператор SQL следующим образом:
DELETE FROM MyTable WHERE (P, ABS((P & 0xFFFFFFFF) * 256 - F)) NOT IN (SELECT P, MIN(ABS((P & 0xFFFFFFFF) * 256 - F)) FROM MyTable GROUP BY P HAVING COUNT(*) > 1)
Но на SQL Server я получу следующую ошибку:
Msg 4145 SQL Server An expression of non-boolean type specified in a context where a condition is expected,near ','
Почему ? Также работает ли поразрядно и & в SQL Server 2005? У меня есть только SQL Server 2008 R2 и в онлайн-документе https://docs.microsoft.com/en-us/sql/t-sql/language-elements/bitwise-and-transact-sql?view=sql-server-ver15 не указано, поддерживает ли он 2005 и 2008 годы.
Update1
P, F, D - все типы bigint.
Update2
С помощью других, я наконец пишу запрос с NOT EXISTS, как показано ниже:
Метод 1: УДАЛИТЬ t ИЗ MyTable t, ГДЕ НЕ СУЩЕСТВУЕТ (ВЫБЕРИТЕ 1 ИЗ (ВЫБРАТЬ P, МИН (ABS ((P & 0xFFFFFFFF) * 256 - F)) как minpf ИЗ ГРУППЫ MyTable ПО P) tt ГДЕ tt .P = tP AND tt.minpf = ABS ((tP & 0xFFFFFFFF) * 256 - tF))
Примечание. Я удаляю HAVE COUNT (*)> 1, в противном случае оператор также будет удалите те записи, которые находятся в группе только с одной записью.
Хотя это работает, я сомневаюсь в его эффективности. Поскольку в большинстве групп (сгруппировать по P) будет только одна запись, при расчете minpf в такой группе и последующем удалении записи с вычисленным значением <> minpf теряется время (в таком случае записи не удаляются). группа). Так что просто интересно, есть ли лучший способ сделать то же самое?
Обновление 3
Я тестирую производительность моего метода (метод 1) с двумя методами Гордон предоставляется (с незначительной ревизией)
Метод 2:
УДАЛИТЬ t ИЗ MyTable t СЛЕДУЮЩЕЕ СОЕДИНЕНИЕ (ВЫБЕРИТЕ P, MIN (ABS ((P & 0xFFFFFFFF) * 256 - F)) как minpf ОТ MyTable GROUP BY P) tt ON tt.p = tp AND tt.minpf = (tt.P & 0xFFFFFFFF) * 256 - tt.F) ГДЕ tt.P НЕДЕЙСТВИТЕЛЬНО;
Метод 3:
УДАЛИТЬ t ОТ (ВЫБРАТЬ t. *, ROW_NUMBER () НАД (РАЗДЕЛЕНИЕ ПО ПОРЯДКУ В АБС ((P & 0xFFFFFFFF) * 256 - F)) как последовательность ОТ MyTable t) t ГДЕ seqnum> 1;
Ниже приведены данные о производительности:
Первый тест:
(затронуто 22721 строк) Метод 1: 16094
(затронут 22721 строк) Метод 2: 17156
(затронуто 22721 строк) Метод 3: 12188
Второй тест:
(затронуто 22721 строк) Метод 1: 26297
(затронуто 22721 строк) Метод 2 : 27562
(затронуто 22721 рядов ) Метод 3: 11625
3-й тест:
(затронуто 22721 строк) Метод 1: 26297
(затронуто 22721 строк) Метод 2: 27359
(Затронуто 22721 строка) Метод 3: 11578
Таким образом, исходя из теста, метод 3 имеет наилучшую производительность.