Suma rekordów nie zgadza się z sumą COUNT bazy danych

Cześć,
Borykam się z jednym problemem, gdyż mam pięć tabel a w nim nazwa użytkownika, kod, adres ip i jak grupuje po kodzie i adresie ip to suma zliczonych wartości COUNT po dodaniu nie zgadza się z sumą wierszy w tabeli. Suma wierszy w tabeli to 35, a po z sumowaniu wartości count, wychodzi 34.
A zapytanie takie jest:
Select id, kod, username, adres_ip from register group by kod, adres_ip order by id
Nie wiem, czemu nie zgadza się ilość z ilością wierszy w tabeli.
Nie wiem już co może być. Coś źle robię?

COUNT() - nie zlicza wartości pustych (NULL)

Druga sprawa to ID/index zaczynający się od „0”. :slight_smile:

Użyj zliczania wszystkich wierszy: COUNT(*)

W przypadku wielu tabel trzeba użyć funkcji UNION (MySQL count() | Guide to How COUNT() Function Work in MySQL) - przykład 7.

W tabeli nie mam pustych wierszy NULL. Z samym COUNT(8) tak robię i nic. Kolejna sprawa w mysql nie działa union, union all, gdyż komunikat wskazuje, że jest to MariaDB. A mam XAMPP wersja php 7.4.
Z Having też próbowałem, ale zlicza ile wystąpień jest powyżej 1.

Select id, kod, username, adres_ip from register group by kod, adres_ip order by id

czemu masz group by w zapytaniu ? wywal.
będzie tyle samo - podwójny wpis jakiś w bazie?
W ogóle to zapytanie wygląda dzieniw z tym gropup by - jest poprawne ?

Zapytanie jest poprawne, i nie wiem dlaczego ma być dziwne. A grupowanie mam, bo chcę zliczać ilość userów z tego samego adresu IP.
Przykład: USer1 192.34.30.4 ilość wejść - 6 i tak dalej. Ja nie chce pobierać wszystkich rekordów, tylko zliczać sumę wejść z danego adresu IP na stronę. Może to dla Ciebie jest dziwne, ale dla mnie nie:)

no bo brakuje w nim counta?
Przyznam się, że nie pamiętam, bo korzystałem głównie z oracle , MSSQL i postgress, ale to powinno wtedy wyglądać tak:

Select adres_ip , count(1) from register group by adres_ip order by adres_ip

Chyba że w mysql jakoś inaczej - przyznam że nie wiem.

Zapomniałem napisać, że w zapytaniu jest COUNT i tego nie dałem, co faktycznie, może dziwić takie zapytanie.

no to teraz rozumiem. :slight_smile:
Czyli… nie zgadza ci sie suma counta z ilością rekordów w bazie?

Tak, ale jak pisałeś, jest tak, że COUNT zlicza od 0 a nie od 1, to wszystko się zgadza. W innym przypadku już nie. Gdy z sumuje wszystkie wartości COUNT, to jest o jeden mniej niż pokazuje liczba wierszy w tabeli. A nawet nie wiem, jak zsumować wartości COUNT. Natrafiam tylko na przykłady z MS SQL, ale w MYSQL nie działa.

Select sum(counter) as sum from (select ip_address, count(1) as counter from register group by ip_address )

coś pewnie w ten deseń

Nie wiem co za teorie tutaj padają. Count nie liczy od 0 zwraca po prostu ilość wierszy zwróconych przez dane zapytanie.

Przykłady dla MuSQL, których nie da się znaleźć: MySQL COUNT() Function

Genezą problemu są dane w tabeli oraz być może używanie group by bez jego zrozumienia.

Drugorzędną kwestią jest wyciąganie tylu danych z bazy po to żeby policzyć wiersze.

Zgaduję bo tego nie wiem ponieważ podałeś za mało informacji (brak próbki danych z jakimi masz problem) że masz 2 takie same adresy lub ip i robisz po nich group by więc wycina Ci duplikaty - czyli możesz mieć mniejszą wartość zwróconą przez count niż wszystkich wierszy w tabeli.

Kolejna kwestia jest taka, że count jest na tyle generyczną funkcją że występuje i działa tak samo w każdym relacyjnym silniku baz danych, więc przykłady powinny działać wszędzie. To sugeruję, ze robisz coś źle bo pewnie używasz count w niepoprawny sposób - dlatego otrzymujesz złe wyniki.


To zdecyduj co chcesz liczyć ilość userów z jednego adresu IP czy ilość wejść jednego usera bo to dwie różne rzeczy. A może w ogóle ilość wejść danego usera z danego adresu IP? Bo jak tak to to jest jeszcze trzecia rzecz.

Ja narazie działam na lokalnym serwerze i mam wszystko z adresu lokalnego, czyli 127.0.0.1. Dlatego mam wszystko z jednego adresu IP, a ja chciałbym, grupować użytkowników po ilość wejść na stronę z danego adresu. I w zasadzie, jak patrzyłem u siebie na innych tabelach, to wszystko jest poprawne, tylko w tej tabeli, gdzie jest 35 wierszy pokazuje mi 34. Dlatego też pisałem o zliczaniu wejść z jednego adresu.
Aby było łatwiej do zrozumienia, to masz stronę, i zapis do tabeli, który zlicza wejścia na stronę. Masz po jakimś czasie 100 wejść wielu użytkowników, ale w tym są użytkownicy, którzy wchodzą po kilkakrotnie z tego samego IP, i teraz chcę pogrupować względem IP. I tak w zasadzie zrobiłem, i działa. Tylko zdziwiłem się, że w tej tabeli pokazuje mi 34 a nie 35 z jednego adresu IP.
Ja wiem, co zaraz będzie napisane, że do zliczania korzysta się JS i zapis do pliku a nie do bazy. To wiem:)
Pierwszy mój wpis dotyczył zapytania dotyczące tabeli register. Ale też tak mam na tabeli, która zapisuje wyniki z kalkulatora BMI razem z adresem IP. I dodaję zrzut ekranu, gdzie widać zapytanie i wynik. Sumy jakie są podane w ile, zgadzają się, bo tylu jest użytkowników. Ale suma wierszy już nie.

Nie, tak się właśnie nie robi. Wszystkie obliczenia które da się zrobić w bazie robi się w bazie bo jest wydajniej. Taka praktyka wynika z tego, że wiele osób umie SQL jedynie na podstawowym poziomie i nie potrafią wykonać zapytań które są nieco bardziej skomplikowane niż te podstawowe lub takie do których przykłady łatwo można znaleźć.

Tutaj masz działający przykład na innych danych bo tylko takie na szybko znalazłem ale analogiczny przypadek. Z tabeli orders wyciągasz informację ile razy każdy pracownik (username) obsługiwał (wszedł na stronę) danego klienta (z danego adresu IP).
Link do bazy online: SQL Tryit Editor v1.6

Zapytanie wyciągające dane opisane wyżej:

SELECT EmployeeID AS `username`, CustomerID AS `IP`, COUNT(CustomerID) AS `Ilosc wejsc` FROM Orders GROUP BY EmployeeID, CustomerID;

Zapytanie dowodzące że uwzględniono wszystkie wiersze z tabeli orders:

SELECT SUM(`Ilosc wejsc`) FROM (SELECT EmployeeID AS `username`, CustomerID AS `IP`, COUNT(CustomerID) AS `Ilosc wejsc` FROM Orders GROUP BY EmployeeID, CustomerID);

Tego nie musisz mi pisać. Tylko niektórzy tak mówią, że można w samym JS. Ale wg.mnie pominęli chyba No SQL. A to też baza danych.

Też to robiłem, ale nie ważne. Popytałem i jest wszystko ok. A te przykłady nie są te, o które mi chodziło. W takim razie, temat można zamknąć.

Jeśli do analityki, to podpiąłbym matomo :slight_smile:

w sensie suma z counta się nie zgadza?

BTW… tam wcześniej miksowałeś w nazwach kolumn polski a zngielskim - wiem czepiam się, ale zawsze mnie to kłuje po oczach :wink:

Wywalić id z selecta ordera i count(1) zamiast count(*) szybsze.

Edit:
obstawiam w sumie głupią rzecz, ale jednak na nią bym postawił :slight_smile:
patrzysz nie na ilość rekordów a na maksymalne ID (35) , a któryś rekord usunąłeś ( czyli jest rekordów 34 faktycznie) , a autoincrement został no i to na pierwszy rzut oka cię męczy :slight_smile:

select count(1) from xlbmi
ile zwraca?

Jak nie podrzucisz próbki danych na której testujesz zapytanie to to jest ciągle takie teoretyzowanie. W bazie możesz mieć różną sytuację której nikt nie będzie w stanie odwzorować na jakiś testowych danych.

To ja kompletnie nie wiem co ty chcesz osiągnąć bo napisałeś że chcesz:

Tak przecież mam. A sprawa dotyczy ilości wierszy a nic nie usuwałem. Jak napisałem wyżej, jest wszystko ok, ale nadal nie mogę z tego zapytania, co wyżej pokazałem na rzucie pobrać sumę z COUNT.

UPDATE
Wykonałem na tej samej tabeli, ale na drugim kompie to samo zapytanie, i mając 22 wiersze, ilość COUNT, też wynosi 22(policzyłem ręcznie). A tabela różni się tylko innym nazewnictwem kolumn.

Dane takie same? Bo może masz inne dane? Group by w połączeniu z count może ba nawet powinien wyciąć duplikaty danych w zależności po czym grupujesz.

Zobacz mój przykład, zapytanie dało mi mniej wierszy niż jest w orders i to chyba o 25, ale w sumie przeanalizowano wszystkie wiersze.

Tak, dane są takie same, czyli z kalkulatora BMI. Różnica jest tylko w nazewnictwie kolumn. A grupuje po nazwie użytkownika i adresie IP, czyli to co pokazałem na zrzucie. Wykonałem jeszcze raz na innej tabeli, dając to samo zapytanie, i suma nie zgadzała się. Gdy wykonałem Truncate tabeli, i ponownie wykonałem powyższe zapytanie, to wszystko się już zgadzało.

Jak wspomniał przedmówca, podeślij próbkę z danymi. Może być jakaś okrojona, byle występował ten sam problem. Osób mocnych w SQL’u tu nie brakuje - migiem otrzymasz odpowiedź