Muszę pobrać wszystkie wiersze z tabeli, w której 2 kolumny łącznie są różne. Chcę więc wszystkich sprzedaży, które nie mają żadnej innej sprzedaży, które miały miejsce tego samego dnia za tę samą cenę. Sprzedaż, która jest unikalna na podstawie dnia i ceny, zostanie zaktualizowana do stanu aktywnego.
Więc myślę:
UPDATE sales
SET status = 'ACTIVE'
WHERE id IN (SELECT DISTINCT (saleprice, saledate), id, count(id)
FROM sales
HAVING count = 1)
Ale mój mózg boli dalej.
sql
postgresql
sql-update
duplicates
distinct
płaszcze
źródło
źródło
Jeśli połączysz dotychczasowe odpowiedzi, posprzątasz i ulepszysz, dojdziesz do tego wyższego zapytania:
Co jest znacznie szybsze niż którekolwiek z nich. Nukuje wydajność obecnie akceptowanej odpowiedzi przez współczynnik 10-15 (w moich testach na PostgreSQL 8.4 i 9.1).
Ale wciąż nie jest to optymalne. Użyj
NOT EXISTS
(anty) półsprzężenia, aby uzyskać jeszcze lepszą wydajność.EXISTS
jest standardowym SQL, istnieje już od zawsze (przynajmniej od PostgreSQL 7.2, na długo przed tym pytaniem) i doskonale spełnia przedstawione wymagania:db <> skrzypce tutaj
Old SQL Fiddle
Unikalny klucz do identyfikacji wiersza
Jeśli nie masz klucza podstawowego lub unikalnego dla tabeli (
id
w tym przykładzie), możesz zastąpić kolumnę systemowąctid
na potrzeby tego zapytania (ale nie do innych celów):Każda tabela powinna mieć klucz podstawowy. Dodaj jeden, jeśli jeszcze go nie masz. Sugeruję kolumnę
serial
lubIDENTITY
Postgres 10+.Związane z:
Jak to jest szybsze?
Podkwerenda w łączeniu
EXISTS
częściowym może przestać oceniać, gdy tylko zostanie znaleziony pierwszy dupe (nie ma sensu szukać dalej). W przypadku tabeli podstawowej z kilkoma duplikatami jest to tylko nieco bardziej wydajne. Z dużą ilością powtórzeń staje sposób bardziej efektywny.Wyklucz puste aktualizacje
W przypadku wierszy, które już mają
status = 'ACTIVE'
tę aktualizację, nic nie zmieni, ale nadal wstaw nową wersję wiersza po pełnym koszcie (obowiązują niewielkie wyjątki). Zwykle tego nie chcesz. Dodaj kolejnyWHERE
warunek, jak pokazano powyżej, aby tego uniknąć i uczynić go jeszcze szybszym:Jeśli
status
jest zdefiniowaneNOT NULL
, możesz uprościć:Typ danych kolumny musi obsługiwać
<>
operatora. Niektóre typy jakjson
nie. Widzieć:Subtelna różnica w obsłudze NULL
To zapytanie (w przeciwieństwie do obecnie akceptowanej odpowiedzi Joela ) nie traktuje wartości NULL jako równych. Poniższe dwa wiersze
(saleprice, saledate)
kwalifikują się jako „odrębne” (choć wyglądają identycznie jak ludzkie oko):Przechodzi również w unikalny indeks i prawie wszędzie indziej, ponieważ wartości NULL nie są równe zgodnie ze standardem SQL. Widzieć:
OTOH,
GROUP BY
,DISTINCT
lubDISTINCT ON ()
wartości NULL traktować jako równe. Użyj odpowiedniego stylu zapytania w zależności od tego, co chcesz osiągnąć. Nadal możesz użyć tego szybszego zapytaniaIS NOT DISTINCT FROM
zamiast z=
jakimkolwiek lub wszystkimi porównaniami, aby wyrównać NULL. Więcej:Jeśli wszystkie porównywane kolumny są zdefiniowane
NOT NULL
, nie ma miejsca na spory.źródło
count(*)
jest bardziej wydajny niżcount(<expression>)
. Po prostu spróbuj. Postgres ma szybszą implementację dla tego wariantu funkcji agregującej. Może mylisz Postgres z innym RDBMS?Problem z zapytaniem polega na tym, że korzystając z klauzuli GROUP BY (co zasadniczo robisz, używając odrębnych), możesz używać tylko kolumn, które grupujesz lub agregujesz. Nie można użyć identyfikatora kolumny, ponieważ istnieją potencjalnie różne wartości. W twoim przypadku zawsze jest tylko jedna wartość z powodu klauzuli HAVING, ale większość RDBMS nie jest wystarczająco inteligentna, aby to rozpoznać.
Powinno to jednak działać (i nie wymaga łączenia):
Możesz także użyć MAX lub AVG zamiast MIN, ważne jest tylko użycie funkcji, która zwraca wartość kolumny, jeśli jest tylko jeden pasujący wiersz.
źródło
Chcę wybrać odrębne wartości z jednej kolumny „GrondOfLucht”, ale należy je posortować w kolejności podanej w kolumnie „sortowanie”. Nie mogę uzyskać odrębnych wartości tylko jednej kolumny
Daje również kolumnę „sortowanie”, a ponieważ „GrondOfLucht” ORAZ „sortowanie” nie jest unikalne, wynikiem będą WSZYSTKIE wiersze.
użyj GRUPY, aby wybrać rekordy „GrondOfLucht” w kolejności podanej przez „sortowanie
źródło
Jeśli Twój DBMS nie obsługuje odrębnych z wieloma takimi kolumnami:
Ogólnie wybór wielokrotny można bezpiecznie wykonać w następujący sposób:
Ponieważ może to działać na większości DBMS i oczekuje się, że będzie to szybsze niż grupowanie według rozwiązania, ponieważ unikasz funkcji grupowania.
źródło