Gå til innhold

Anbefalte innlegg

Jeg har prøver å lage en database for gocart-tider, og synes at jeg har kommet godt igang.

Det er fire tabeller (drivers, heats, heat_cart og laps), men bare den ene (laps) er vesentlig her. Tabellen laps ser slik ut:

mysql> DESCRIBE gocart_laps;
+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| lap_id    | int(11) | NO   | PRI | NULL    | auto_increment | 
| driver_id | int(11) | NO   |     |         |                | 
| time      | float   | NO   |     |         |                | 
| heat      | int(11) | NO   |     |         |                | 
| lap       | int(3)  | NO   |     |         |                | 
+-----------+---------+------+-----+---------+----------------+

Der lagrer jeg altså hver eneste rundetid (kolonnen time, oppgitt i sekunder) og kan finne igjen både fører, hvilket heat det var og hvilken runde i heatet det var.

 

For å finne beste tiden til en gitt fører kan jeg skrive: SELECT MIN(time) FROM laps WHERE driver_id = [nummer];. Men jeg vil også finne ut hvilken runde og hvilket heat det var. Hvis jeg prøver SELECT MIN(time), heat, lap FROM laps WHERE driver_id = [nummer];, må jeg også legge inn GROUP BY driver_id, og da kommer det bare ut første heatet og første runden som er registrert på den føreren.

mysql> SELECT driver_id, MIN(time), heat, lap FROM gocart_laps GROUP BY driver_id;
+-----------+-----------+------+-----+
| driver_id | MIN(time) | heat | lap |
+-----------+-----------+------+-----+
|         1 |     43.25 |    1 |   1 | 
|         2 |     45.21 |    1 |   1 | 
|         3 |     58.74 |    2 |   1 | 
|         4 |     44.13 |    1 |   1 | 
|         5 |     46.88 |    1 |   1 | 
|         6 |     47.59 |    1 |   1 | 
|         7 |     49.62 |    1 |   1 | 
|         8 |     44.04 |    1 |   1 | 
+-----------+-----------+------+-----+

 

Hva må jeg bruke for å få til det jeg vil?

Endret av endrebjorsvik
Lenke til kommentar
Videoannonse
Annonse

sikkert ikke en god løsning, men hadde det funket med:

 

SELECT * from laps where driver_id=?? order by time asc limit 1

 

 

Lenge siden jeg har brukt sql, så husker ikke rekkefølgen på staementene nøyaktig, men du sorterer på rundetid og plukker ut kun den beste runden.

 

Forresten, hva gjør du om bestetiden til en fører blir gjentatt? da vil du jo ha 2 runder som er "beste runde"

Lenke til kommentar

Den funker fint den måten, men da blir det tungvindt å hente ut flere førere samtidig (én spørring pr. fører).

 

Det med like rundetider hadde jeg faktisk ikke tenkt på. Så lenge databasen spytter ut den første runden, så holder vel egentlig det. Når den runden først er gjort, så spiller jo ikke den andre runden så veldig stor rolle når den ikke var raskere enn den første.

Lenke til kommentar

Det er samme spørringen som i kodeboks nr. 2 i førsteinnlegget, så jeg får ut de samme resultatene:

mysql> SELECT MIN( time ), driver_id, heat, lap
   -> FROM gocart_laps GROUP BY driver_id;
+-------------+-----------+------+-----+
| MIN( time ) | driver_id | heat | lap |
+-------------+-----------+------+-----+
|       43.25 |         1 |    1 |   1 | 
|       45.21 |         2 |    1 |   1 | 
|       58.74 |         3 |    2 |   1 | 
|       44.13 |         4 |    1 |   1 | 
|       46.88 |         5 |    1 |   1 | 
|       47.59 |         6 |    1 |   1 | 
|       49.62 |         7 |    1 |   1 | 
|       44.04 |         8 |    1 |   1 | 
+-------------+-----------+------+-----+
8 rows in set (0.00 sec)

Lenke til kommentar

mysql> SELECT * FROM gocart_laps WHERE driver_id = 1;
+--------+-----------+-------+------+-----+
| lap_id | driver_id | time  | heat | lap |
+--------+-----------+-------+------+-----+
|      2 |         1 | 46.07 |    1 |   1 | 
|      3 |         1 | 45.68 |    1 |   2 | 
|      4 |         1 | 45.28 |    1 |   3 | 
|      5 |         1 | 48.15 |    1 |   4 | 
|      6 |         1 | 44.58 |    1 |   5 | 
|      7 |         1 |    47 |    1 |   6 | 
|      8 |         1 |    45 |    1 |   7 | 
|      9 |         1 | 44.24 |    1 |   8 | 
|     10 |         1 | 44.39 |    1 |   9 | 
|     11 |         1 | 45.48 |    1 |  10 | 
|     12 |         1 |  44.8 |    1 |  11 | 
|     13 |         1 | 45.62 |    1 |  12 | 
|     77 |         1 | 45.34 |    2 |   1 | 
|     78 |         1 | 44.52 |    2 |   2 | 
|     79 |         1 | 60.89 |    2 |   3 | 
|     80 |         1 | 54.54 |    2 |   4 | 
|     81 |         1 | 47.04 |    2 |   5 | 
|     82 |         1 | 44.97 |    2 |   6 | 
|     83 |         1 | 44.14 |    2 |   7 | 
|     84 |         1 | 44.95 |    2 |   8 | 
|     85 |         1 | 43.25 |    2 |   9 | 
|     86 |         1 | 51.08 |    2 |  10 | 
|     87 |         1 | 43.34 |    2 |  11 | 
|     88 |         1 | 44.52 |    2 |  12 | 
|     89 |         1 | 51.98 |    2 |  13 | 
|     90 |         1 | 43.88 |    2 |  14 | 
+--------+-----------+-------+------+-----+
26 rows in set (0.07 sec)

Minstetiden (43,25 sek) er i heat 2, lap 9.

Endret av endrebjorsvik
Lenke til kommentar
Du får se om du blir klok på 11.11.3. GROUP BY and HAVING with Hidden Fields

9241805[/snapback]

Jeg er litt usikker på hva det kapittelet prøver å fortelle. Er det det at man må oppgi alle feltene i GROUP BY i standard SQL, mens MySQL slenger resten av feltene med automatisk for å gjøre jobben enklere?

(noe ala. det blackbrrd sier om forskjellen mellom MySQL og PostgreSQL)

 

 

Er vant med å bruke postgres, og der må du kjøre group by på alle feltene i select clausen... Prøv det du også:

SELECT driver_id, MIN(time), heat, lap FROM gocart_laps GROUP BY driver_id, heat, lap;

9243831[/snapback]

Der spytter den ut alle de registrerte tidene i databasen (akkurat som SELECT * FROM gocart_laps). Det hadde jeg egentlig forventet, siden den da grupperer etter alle mulige kombinasjoner av driver_id, heat og lap, som da blir alle registrerte resultater (vanskelig å forklare hvordan jeg ser det for meg og tenker :p ).

Vil den bli riktig hvis jeg hiver alt inn i en PgSQL-database?

Lenke til kommentar

mySql sin implementasjon følger nok ikke sql standarden nei, men det hjelper ikke, med group by på alle kolonnene vil du få ut det samme som om du bare hadde kjørt en vanlig select * from tablename.

 

Jeg vet om flere triks som fikser problemet ditt, men aner ikke om de funker i mysql...

 

Forslag #1

 

SELECT a.* FROM gocart_laps as a

INNER JOIN (

SELECT driver_id, MIN(time) as mintime FROM gocart_laps GROUP BY driver_id) as foo ON foo.driver_id = a.driver_id AND foo.mintime = a.time

 

Hvis du har to rundetider som er like bra for en driver_id vil du få ut en random gocart_laps rad av de to.

Endret av blackbrrd
Lenke til kommentar

Forslag #1 funker fint i både MySQL og PgSQL (nettopp installert det). Men der er det jo også i realiteten flere spørringer (subqueries). Er det uunngåelig i dette tilfellet?

 

 

Og et lite kjapt spørsmål og PgSQL.

Hva trykker jeg for å skrive en ny spørring når terminalen ser slik ut:

post-30930-1186780383_thumb.png

Det er en helt vanlig SELECT-query i PgSQL som er lengre enn vinduet. Da begynner en eller annen rar scrolle-funksjon som jeg ikke kommer ut av. Ctrl+Z funker, men da avsluttes psql også.

Lenke til kommentar

Bruker personlig pgadmin for å administrere posgressql databasene jeg er admin for.

 

http://www.postgresql.org/ftp/pgadmin3/release/v1.6.3/

 

Der vil du kunne kjøre til fil, skjerm eller hva du vil egentlig... Det er også en veldig bra analyze funksjon som viser grafisk hva den gjør for å hente dataene. Uvurdelig når du har en svær query med 20 joins og du lurer på hvorfor den er treg... Da er det bare å lete etter en svær feit pil og identifisere f.eks mangel på index på det databasen skal slå opp på.

 

Vet ikke helt om det går an å unngå subqueries eller lignende i dette tilfellet... Det er mulig en annen datastruktur hadde vært bedre for denne oppgaven.

Endret av blackbrrd
Lenke til kommentar
Bruker personlig pgadmin for å administrere posgressql databasene jeg er admin for.

http://www.postgresql.org/ftp/pgadmin3/release/v1.6.3/

Der vil du kunne kjøre til fil, skjerm eller hva du vil egentlig... Det er også en veldig bra analyze funksjon som viser grafisk hva den gjør for å hente dataene. Uvurdelig når du har en svær query med 20 joins og du lurer på hvorfor den er treg... Da er det bare å lete etter en svær feit pil og identifisere f.eks mangel på index på det databasen skal slå opp på.

9254913[/snapback]

Kult program. Det lå faktisk i Synaptics.

 

 

Og et lite kjapt spørsmål og PgSQL.

Hva trykker jeg for å skrive en ny spørring når terminalen ser slik ut:

Har du prøvd tasten q? Kan se ut som om det skal funke, uten at jeg har prøvd det selv.

9255264[/snapback]

q-tasten funker fett! Takk! :D
Lenke til kommentar

Gidder du å poste ett bilde av hvordan queryen jeg postet blir kjørt (den grafisk mao)?

 

(denne mao:

SELECT a.* FROM gocart_laps as a

INNER JOIN (

SELECT driver_id, MIN(time) as mintime FROM gocart_laps GROUP BY driver_id) as foo ON foo.driver_id = a.driver_id AND foo.mintime = a.time

)

 

Noe tilsvarende vedlegget mao

post-9522-1186868266_thumb.jpg

Endret av blackbrrd
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...