Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> Brak pomysłu na zapytanie mysql
lolo121
post 20.10.2017, 19:50:49
Post #1





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cześć, mam w bazie kilkaset tysięcy rekordów, które bardzo często mają identyczną nazwę, dajmy na to "name", jednak ich wartość (np. pole "wartosc") są różne, jedne małe, inne większe. Potrzebuję skonstruować zapytanie, które wybierze mi z bazy wszystkie unikalne "name" (tylko jeden raz), ale w taki sposób, że wybierze to unikalne "name" o możliwie najmniejszej wartości z pola "wartosc". Każdy rekord ma również swoją datę, według której chcę posortować rekordy z unikalnymi nazwami i najmniejszymi wartościami od najnowszej do najstarszej, czyli "order by data desc". Przykład - w bazie są takie dane:

name | wartość | data
aaa | 1.05 | 17.10.2017
bbb | 43.21 | 18.10.2017
bbb | 32.94 | 19.10.2017
aaa | 2.43 | 12.10.2017
ccc | 322.32 | 20.10.2017
bbb | 23.11 | 16.10.2017
aaa | 1.32 | 14.10.2017
ccc | 411.21 | 18.10.2017
ccc | 409.30 | 19.10.2017

Na stronie wynik z zapytania powinien tak wyglądać:

ccc | 322.32 | 20.10.2017
aaa | 1.05 | 17.10.2017
bbb | 23.11 | 16.10.2017

Czy pomógłby mi ktoś ze skonstruowaniem zapytania, które wykona takie coś, przy czym te zapytanie będzie możliwie najbardziej wydajne? Z bazą łączę się wykorzystując PDO. Dzięki za pomoc.
Go to the top of the page
+Quote Post
trueblue
post 20.10.2017, 20:06:59
Post #2





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


  1. SELECT t1.name, t1.wartosc, t1.DATA
  2. FROM tabela AS t1
  3. JOIN tabela AS t2 ON t1.name=t2.name AND t1.wartosc>=t2.wartosc
  4. GROUP BY t1.id
  5. HAVING COUNT(*) <= 1

Nie ma tu ORDER BY - nawet nie sprawdzałem, nie wiem czy na takim formacie jaki stosujesz poprawnie zadziała.


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 13:14:29
Post #3





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 20.10.2017, 21:06:59 ) *
  1. SELECT t1.name, t1.wartosc, t1.DATA
  2. FROM tabela AS t1
  3. JOIN tabela AS t2 ON t1.name=t2.name AND t1.wartosc>=t2.wartosc
  4. GROUP BY t1.id
  5. HAVING COUNT(*) <= 1

Nie ma tu ORDER BY - nawet nie sprawdzałem, nie wiem czy na takim formacie jaki stosujesz poprawnie zadziała.


Dzięki za odpowiedź, niestety zapytanie powoduje wczytywanie strony w nieskończoność, nawet jak danych jest bardzo mało. Zapomniałem, że szybko polecenia można sprawdzać w phpmyadmin - zrobiłem takie i daje wynik bardzo bliski tego, który zamierzam osiągnąć

  1. SELECT id, name, DATA, wartosc FROM tabela GROUP BY name ORDER BY id DESC, wartosc ASC


Spróbuję to jakoś poprawić i może się uda
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 13:26:38
Post #4





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Na danych, które podałeś w poprzednim poście zapytanie nie wykonuje się w nieskończoność i wynik jest poprawny.


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 14:44:41
Post #5





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 14:26:38 ) *
Na danych, które podałeś w poprzednim poście zapytanie nie wykonuje się w nieskończoność i wynik jest poprawny.


Powinienem już na początku przedstawić strukturę bazy danych

# | Nazwa | Typ | Metoda porównywania napisów | Null | Ustawienia domyślne
1 | id | int(11) | Nie | Brak | AUTO_INCREMENT
2 | name | text | utf8_polish_ci | Nie
3 | wartosc | text | utf8_polish_ci | Nie
4 | data | text | utf8_polish_ci | Nie | Brak

data u mnie jest tekstem, przechowuję ją już w odpwoiednim formacie - w razie czego nie ma problemu z utworzeniem zamiast niej pola timestamp i skonwertowaniu przetworzonej data do timestamp
wartosc także jest tekstem, bo występują w niej znaki np. "." i ":" - sortowanie według niej działa poprawnie, sortowanie wg. przetworzonej data niestety nie - wybiera najpierw 31 dzień miesięcy, potem 30 itd.

Ten post edytował lolo121 22.10.2017, 14:46:01
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 14:48:44
Post #6





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


O ile pole typu TEXT z kropką można traktować jako FLOAT lub DECIMAL, to jakie znaczenie ma dwukropek w tym polu?


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 15:09:17
Post #7





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 15:48:44 ) *
O ile pole typu TEXT z kropką można traktować jako FLOAT lub DECIMAL, to jakie znaczenie ma dwukropek w tym polu?


dwukropek określa ilość minut
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 15:10:49
Post #8





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Pokaż przykładowe wartości.


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 15:16:53
Post #9





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 16:10:49 ) *
Pokaż przykładowe wartości.


przykładowo

12:26.2 czyli 12 minut : 26 sekund . 2 milisekundy

inne wpisy różnią się cyframi, np. 28:53.6, 142:41.5 itp.


a przetworzone pole data ma taki format: 22.10.2017 16:14:10 - to nie jest timestamp, tylko sam text
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 15:21:54
Post #10





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


A jak wygląda:
- czas bez minut
- czas z sekundami poniżej 10
?


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 15:27:41
Post #11





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 16:21:54 ) *
A jak wygląda:
- czas bez minut
- czas z sekundami poniżej 10
?


bez minut: 000:43.3
poniżej 10 sekund: 000:02.6

ASC / DESC sortuje je poprawnie

Ten post edytował lolo121 22.10.2017, 15:29:08
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 15:42:16
Post #12





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Nie zmienia się zasada działania oprócz cast'owania czasu na wartość zmiennoprzecinkową i sortowania.
  1. SELECT t1.name, t1.wartosc, t1.DATA
  2. FROM tabela AS t1
  3. JOIN tabela AS t2 ON t1.name=t2.name AND CAST(REPLACE(t1.wartosc,':','') AS DECIMAL(10,2))>= CAST(REPLACE(t2.wartosc,':','') AS DECIMAL(10,2))
  4. GROUP BY t1.id
  5. HAVING COUNT(*) <= 1
  6. ORDER BY DATA DESC


http://sqlfiddle.com/#!9/cb0cc0/2/0


--------------------
Go to the top of the page
+Quote Post
lolo121
post 22.10.2017, 17:03:59
Post #13





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 16:42:16 ) *
Nie zmienia się zasada działania oprócz cast'owania czasu na wartość zmiennoprzecinkową i sortowania.
  1. SELECT t1.name, t1.wartosc, t1.DATA
  2. FROM tabela AS t1
  3. JOIN tabela AS t2 ON t1.name=t2.name AND CAST(REPLACE(t1.wartosc,':','') AS DECIMAL(10,2))>= CAST(REPLACE(t2.wartosc,':','') AS DECIMAL(10,2))
  4. GROUP BY t1.id
  5. HAVING COUNT(*) <= 1
  6. ORDER BY DATA DESC


http://sqlfiddle.com/#!9/cb0cc0/2/0


Przeprowadziłem zapytanie na mniejszej liczbie danych - 5000 rekordów. Zapytanie faktycznie działa, tylko że przetwarza się bardzo długo

Cytat
Pokazano wiersze 0 - 24 (164 ogółem, Wykonanie zapytania trwało 24.1821 sekund(y).)


24 sekundy zajęło przetworzenie 5000 rekordów, a w bazie mam ich kilkaset tysięcy
Go to the top of the page
+Quote Post
trueblue
post 22.10.2017, 17:26:49
Post #14





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


To trzeba założyć indeksy na polach name i data. Nie wiem czy coś pomoże na polu wartosc, ale przydałby się na pewno.
A jeszcze lepiej by było gdyby pole wartosc było zapisane od razu w bazie danych w postaci po konwersji (zdublowane dane) i na tej przekonwertowanej kolumnie indeks i łączenie.


--------------------
Go to the top of the page
+Quote Post
Pilsener
post 24.10.2017, 07:36:32
Post #15





Grupa: Zarejestrowani
Postów: 1 590
Pomógł: 185
Dołączył: 19.04.2006
Skąd: Gdańsk

Ostrzeżenie: (0%)
-----


  1. SELECT * FROM (SELECT * FROM `table` ORDER BY `value`) AS t GROUP BY `name` ORDER BY `date`


Niestety tego typu przeliczenia nigdy nie są szybkie, można:
- użyć lepszego zapytania (stosując zmienne, pętle etc.)
- użyć cache
- zmienić model danych (to polecam), zbudować pomocniczą tabelę/widok z duplikatami i przeliczać ją bezpośrednio po zmianie tabeli podstawowej lub co jakiś czas
Go to the top of the page
+Quote Post
lolo121
post 27.10.2017, 20:27:24
Post #16





Grupa: Zarejestrowani
Postów: 26
Pomógł: 0
Dołączył: 28.09.2014

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 22.10.2017, 18:26:49 ) *
To trzeba założyć indeksy na polach name i data. Nie wiem czy coś pomoże na polu wartosc, ale przydałby się na pewno.
A jeszcze lepiej by było gdyby pole wartosc było zapisane od razu w bazie danych w postaci po konwersji (zdublowane dane) i na tej przekonwertowanej kolumnie indeks i łączenie.



Cytat(Pilsener @ 24.10.2017, 08:36:32 ) *
  1. SELECT * FROM (SELECT * FROM `table` ORDER BY `value`) AS t GROUP BY `name` ORDER BY `date`


Niestety tego typu przeliczenia nigdy nie są szybkie, można:
- użyć lepszego zapytania (stosując zmienne, pętle etc.)
- użyć cache
- zmienić model danych (to polecam), zbudować pomocniczą tabelę/widok z duplikatami i przeliczać ją bezpośrednio po zmianie tabeli podstawowej lub co jakiś czas


Strukturę bazy zawsze mogę przebudować, jednak potrzebowałem czegoś działającego w miarę szybko pod obecną strukturę. Spróbowałem samemu zrobić i udało się takim poleceniem

  1. SELECT id, name, DATA, MIN(wartosc) FROM tabela GROUP BY name ORDER BY id DESC


Działa całkiem szybko, dokładnie tak, jak chciałem i na razie wystarcza na moje potrzeby, przy tym jest prosto zbudowane

Ten post edytował lolo121 27.10.2017, 20:29:38
Go to the top of the page
+Quote Post
trueblue
post 27.10.2017, 20:37:18
Post #17





Grupa: Zarejestrowani
Postów: 6 761
Pomógł: 1822
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Poprawne wyniki Twojego zapytania (w szczególności wartości id i data w grupie) są dziełem przypadku i nie możesz na nich polegać.

Cytat
The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Result set sorting occurs after values have been chosen, and ORDER BY does not affect which values within each group the server chooses.

https://dev.mysql.com/doc/refman/5.6/en/gro...y-handling.html


--------------------
Go to the top of the page
+Quote Post
StevDefs
post 27.08.2019, 05:59:51
Post #18





Grupa: Zarejestrowani
Postów: 51
Pomógł: 0
Dołączył: 22.08.2019

Ostrzeżenie: (10%)
X----


Nuevo Progreso Mexico Pharmacies Wirkung Cialis Erfahrung generic viagra Buying Lasix Online Direct Worldwide Progesterone Best Website In Canada Cheapeast

Buy Disulfiram Cialis From India Propecia Cantidad viagra Cialis Y Fertilidad Dutasteride 0.5mg Avidart Sale Discount Canadin Drugs

Amoxicillin Coughing cialis Precio De Cialis Generico En Aguascalientes

Clofazimine Lasilix Where To Buy Non Precription Viagra Zoll order cialis online I Ran Out Of My Aciphex

Antibiotics Online Order With Paypal Cialis Romania Cialis 5 Mg Online Without Prescription buy viagra online The Best Generic Cialis

Venta De Kamagra Contrareembolso Propecia Hair Line 5mg cialis Doxycycline Shop Buy Accutane Uk No Prescription

Kamagra Preisvergleich cialis no prescription Kwikmed Coupon Viagra Want To Buy Amoxicilina Overseas

Amoxicillin Children'S Dosage Is Cephalexin Good For Sinus Infections Homoopathie Levitra buy generic cialis Cialis Es Con Receta Orlistat 60mg Nolvadex Vente

Cialis Sonnolenza Get Elocon 0.1% In Canada viagra Best Brand Viagra Priligy Usa Approbation

Tadalafil Generic 40 Mg India Cialis Ou Viagra Forum canadian cialis Propecia Prescription Buy Kamagra Oral Jelly London
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 28.03.2024 - 16:33