Czy istnieje lepszy sposób wykonania takiego zapytania:
SELECT COUNT(*)
FROM (SELECT DISTINCT DocumentId, DocumentSessionId
FROM DocumentOutputItems) AS internalQuery
Muszę policzyć liczbę odrębnych pozycji z tej tabeli, ale odrębność dotyczy dwóch kolumn.
Moje zapytanie działa dobrze, ale zastanawiałem się, czy mogę uzyskać końcowy wynik za pomocą tylko jednego zapytania (bez użycia pod-zapytania)
sql
sql-server
performance
tsql
query-optimization
Nowicki
źródło
źródło
Odpowiedzi:
Jeśli próbujesz poprawić wydajność, możesz spróbować utworzyć utrwaloną kolumnę obliczeniową na podstawie wartości skrótu lub konkatenacji dwóch kolumn.
Po utrwaleniu, pod warunkiem, że kolumna jest deterministyczna i używasz „zdrowych” ustawień bazy danych, można ją indeksować i / lub tworzyć na niej statystyki.
Uważam, że odrębna liczba obliczonych kolumn byłaby równoważna z zapytaniem.
źródło
Edycja: Zmieniony z mniej niż wiarygodnego zapytania zawierającego tylko sumę kontrolną Odkryłem sposób na to (w SQL Server 2005), który działa całkiem dobrze dla mnie i mogę użyć tyle kolumn, ile potrzebuję (dodając je do funkcja CHECKSUM ()). Funkcja REVERSE () przekształca ints w varchary, aby uczynić wyróżnienie bardziej niezawodnym
źródło
Co takiego jest w twoim istniejącym zapytaniu, czego nie lubisz? Jeśli się tym martwisz
DISTINCT
dwie kolumny nie zwracają tylko unikatowych permutacji, spróbuj tego?Z pewnością działa tak, jak można oczekiwać w Oracle.
edytować
Poszedłem ślepą uliczką z analizami, ale odpowiedź była przygnębiająco oczywista ...
edycja 2
Biorąc pod uwagę następujące dane, powyższe rozwiązanie konkatenacyjne zostanie przelane:
Więc dołączymy separator ...
Oczywiście wybrany separator musi być znakiem lub zestawem znaków, które nigdy nie mogą pojawić się w żadnej kolumnie.
źródło
Aby uruchomić jako pojedyncze zapytanie, połącz kolumny, a następnie uzyskaj odrębną liczbę wystąpień połączonego łańcucha.
W MySQL możesz zrobić to samo bez kroku konkatenacji w następujący sposób:
Ta funkcja jest wspomniana w dokumentacji MySQL:
http://dev.mysql.com/doc/refman/5.7/en/group-by-functions.html#function_count-distinct
źródło
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
Co powiesz na coś takiego:
Prawdopodobnie robi to samo, co już jesteś, ale unika to DISTINCT.
źródło
GROUP BY
może wprowadzić kilka dodatkowych wyzwań do transformacji zapytania w celu uzyskania pożądanego wyniku (np. Gdy pierwotne zapytanie już zawierałoGROUP BY
lub zawierałoHAVING
klauzule ...)Oto krótsza wersja bez podselekcji:
Działa dobrze w MySQL i myślę, że optymalizator ma łatwiejszy czas na zrozumienie tego.
Edycja: Najwyraźniej źle odczytałem MSSQL i MySQL - przepraszam za to, ale może i tak to pomaga.
źródło
count ( distinct CHECKSUM ([Field1], [Field2])
Wiele (większość?) Baz danych SQL może współpracować z krotkami takimi jak wartości, więc możesz po prostu to zrobić:
SELECT COUNT(DISTINCT (DocumentId, DocumentSessionId)) FROM DocumentOutputItems;
jeśli twoja baza danych tego nie obsługuje, można ją zasymulować zgodnie z sugestią @ oncel-umut-turer dotyczącą CHECKSUM lub innej funkcji skalarnej zapewniającej dobrą wyjątkowość npCOUNT(DISTINCT CONCAT(DocumentId, ':', DocumentSessionId))
.Powiązanym zastosowaniem krotek jest wykonywanie
IN
zapytań, takich jak:SELECT * FROM DocumentOutputItems WHERE (DocumentId, DocumentSessionId) in (('a', '1'), ('b', '2'));
źródło
select count(distinct(a, b))
? : DW zapytaniu nie ma nic złego, ale możesz to zrobić w ten sposób:
źródło
Mam nadzieję, że to działa Piszę na prima vista
źródło
Zastosowałem to podejście i zadziałało dla mnie.
W moim przypadku zapewnia prawidłowy wynik.
źródło
jeśli masz tylko jedno pole do „DISTINCT”, możesz użyć:
i to zwraca ten sam plan zapytań co oryginał, co przetestowano przy użyciu SET SHOWPLAN_ALL ON. Jednak używasz dwóch pól, aby wypróbować coś szalonego:
ale będziesz mieć problemy, jeśli zaangażowane są wartości NULL. Pozostałbym przy pierwotnym zapytaniu.
źródło
Znalazłem to, gdy poszukałem Google'a w związku z moim problemem, stwierdziłem, że jeśli policzysz obiekty DISTINCT, otrzymasz poprawną liczbę (używam MySQL)
źródło
DocumentId
aDocumentSessionId
). Alexander Kjäll już opublikował poprawną odpowiedź, jeśli OP używa MySQL, a nie MS SQL Server.Chciałbym, aby MS SQL mógł zrobić coś w rodzaju COUNT (DISTINCT A, B). Ale nie może.
Na początku odpowiedź JayTee wydawała mi się rozwiązaniem po kilku testach CHECKSUM () nie udało się stworzyć unikalnych wartości. Szybki przykład jest taki, że zarówno CHECKSUM (31 467 519), jak i CHECKSUM (69 1120 823) daje tę samą odpowiedź, która wynosi 55.
Później przeprowadziłem badania i odkryłem, że Microsoft NIE zaleca korzystania z funkcji CHECKSUM do wykrywania zmian. Na niektórych forach niektórzy sugerowali użycie
ale to również nie jest wygodne.
Możesz użyć funkcji HASHBYTES () zgodnie z sugestią w zagadce TSQL CHECKSUM . Ma to jednak niewielką szansę na nie zwrócenie unikatowych wyników.
Sugerowałbym użycie
źródło
Co powiesz na to,
Otrzymamy w ten sposób liczbę wszystkich możliwych kombinacji DocumentId i DocumentSessionId
źródło
Mi to pasuje. W wyroczni:
W jpql:
źródło
Miałem podobne pytanie, ale zapytanie, które zadałem, było zapytaniem cząstkowym z danymi porównawczymi w zapytaniu głównym. coś jak:
ignorując złożoność tego, zdałem sobie sprawę, że nie mogę wprowadzić wartości a.code do podzapytania za pomocą podwójnego zapytania podrzędnego opisanego w pierwotnym pytaniu
W końcu doszedłem do wniosku, że mogę oszukiwać i łączyć kolumny:
To właśnie skończyło się na pracy
źródło
Jeśli pracujesz z typami danych o stałej długości, możesz rzutować, aby
binary
to zrobić bardzo łatwo i bardzo szybko. Zakładając,DocumentId
iDocumentSessionId
to zarównoint
s, a zatem są 4 bajty długo ...Mój specyficzny problem wymagał ode mnie podzielenia
SUM
przezCOUNT
odrębną kombinację różnych kluczy obcych i pola daty, grupowania według innego klucza obcego i czasami filtrowania według określonych wartości lub kluczy. Tabela jest bardzo duża, a użycie zapytania częściowego znacznie wydłużyło czas zapytania. Ze względu na złożoność statystyki po prostu nie były realną opcją.CHECKSUM
Rozwiązaniem było również zbyt powolne w jego konwersji, szczególnie w wyniku różnych typów danych, a ja nie mogłem ryzykować jego zawodność.Jednak użycie powyższego rozwiązania praktycznie nie wydłużyło czasu zapytania (w porównaniu z użyciem po prostu
SUM
) i powinno być całkowicie niezawodne! Powinien być w stanie pomóc innym w podobnej sytuacji, więc zamieszczam to tutaj.źródło
Możesz po prostu użyć funkcji Count Count dwa razy.
W takim przypadku byłoby to:
źródło
Ten kod używa odrębnego dla 2 parametrów i podaje liczbę wierszy charakterystyczną dla liczby różnych wierszy. W MySQL zadziałało to jak urok.
źródło