Если вы соберете ответы, очистите и улучшите их, вы получите следующий превосходный запрос:
UPDATE sales
SET status = 'ACTIVE'
WHERE (saleprice, saledate) IN (
SELECT saleprice, saledate
FROM sales
GROUP BY saleprice, saledate
HAVING count(*) = 1
);
, который на намного быстрее, чем любой из них. Уменьшает производительность принятого в настоящее время ответа в 10-15 раз (в моих тестах на PostgreSQL 8.4 и 9.1).
1146 Но это все еще далеко от оптимального. Используйте NOT EXISTS
(анти-) полусоединение для еще лучшей производительности. EXISTS
является стандартным SQL, существует вечно (по крайней мере, с PostgreSQL 7.2, задолго до того, как был задан этот вопрос) и идеально соответствует представленным требованиям:
UPDATE sales s
SET status = 'ACTIVE'
WHERE NOT EXISTS (
SELECT FROM sales s1 -- SELECT list can be empty for EXISTS
WHERE s.saleprice = s1.saleprice
AND s.saledate = s1.saledate
AND s.id <> s1.id -- except for row itself
)
AND s.status IS DISTINCT FROM 'ACTIVE'; -- avoid empty updates. see below
db <> fiddle здесь
Старая скрипта SQL
Если у вас нет основного или уникального Ключ для таблицы (id
в примере), вы можете заменить системный столбец ctid
для целей этого запроса (но не для некоторых других целей):
AND s1.ctid <> s.ctid
Каждая таблица должна иметь первичный ключ. Добавьте еще один, если у вас его еще не было. Я предлагаю столбец serial
или IDENTITY
в Postgres 10+.
Связанные:
Подзапрос в EXISTS
anti-semi-join может перестать оценивать, как только будет найден первый дуплекс (нет смысла смотреть дальше). Для базовой таблицы с небольшим количеством дубликатов это лишь немного более эффективно. С большим количеством дубликатов это становится способом более эффективным.
Для строк, в которых уже есть status = 'ACTIVE'
, это обновление ничего не изменит, но все равно вставит новую версию строки за полную стоимость (применяются незначительные исключения). Обычно вы этого не хотите. Добавьте еще одно условие WHERE
, как показано выше, чтобы избежать этого и сделать его еще быстрее:
Если определено status
NOT NULL
, вы можете упростить до:
AND status <> 'ACTIVE';
Этот запрос (в отличие от принятого в настоящее время ответа Джоэля ) не рассматривает значения NULL как равные. Следующие две строки для (saleprice, saledate)
будут квалифицироваться как «отличные» (хотя они выглядят идентично человеческому глазу):
(123, NULL)
(123, NULL)
Также передает уникальный индекс и почти в любом другом месте, поскольку значения NULL не сравниваются равен по стандарту SQL. См.
OTOH, GROUP BY
, DISTINCT
или DISTINCT ON ()
обрабатывают значения NULL как равные , Используйте соответствующий стиль запроса в зависимости от того, чего вы хотите достичь. Вы все еще можете использовать этот более быстрый запрос с IS NOT DISTINCT FROM
вместо =
для любого или всех сравнений, чтобы сделать сравнение NULL равным. Подробнее:
Если все сравниваемые столбцы определены NOT NULL
, в нем нет места разногласие. [тысяча сто пятьдесят семь]
Я использую synergy для управления всеми моими настольными компьютерами и ноутбуками в одной локальной сети с помощью основной клавиатуры и мыши. Я предполагаю, что у вас в Pi установлен какой-то рабочий стол, например Ubuntu или Debian.
Кроме того, если вы просто хотите получить доступ через командную строку, установите openssh-server и openssh-client в Pi, и вы можете войти, используя IP в локальной сети.