SQL och sortering

Tråden skapades och har fått 6 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Stockholm
  • 2003-04-30 13:55

Hej!

Håller på med ett korpfotbollssystem för mitt korplag. Jag har tidigare haft en helt egen tabell för att spara värden där alla lagens poäng, gjorda mål osv. står.
Nu har jag läst SQL i skolan och inser att de flesta av dessa värden lika gärna kan räknas ut direkt och skrivas ut i ett table.

Vad som krånglar är bara det här med poängen. Man får ju 3poäng för en vunnen match, 1 för oavgjord och 0 vid förlust.
Problemet uppstår i och med att folk ska välja själva vad dom vill sortera efter... antingen lagnamn, gjorda mål, insläppta mål, förlorade matcher.. ja ni förstår.
Men hur gör jag för att kunna sortera efter poäng?

I matchtabellen står vilket lag som är hemma och vilket som är borta och sedan båda lagens resultat. Utifrån det kan man ju räkna ut vilket lag som vunnit och så men..

Funderar på om jag skall skapa en array och fylla den med värdena och på något vänster sortera utifrån den (då har jag ju konkreta värden sparade)... hämtar jag ifrån tabellen måste jag ju göra någon form av "if ($vinst) $poang+=3" eller något.

Hoppas någon kan tyda min dåliga förklaring

mvh
/ivar

  • Medlem
  • 2003-04-30 17:17

I SQL finns ju group by vilket gör det enkelt att räkna ut en summa, hitta max eller
min värden etc. Följande lilla exempel kanske kan vara till någon hjälp.

mysql> desc lag;
+---------+-------------+------+-----+---------+-------+
| Field   | Type        | Null | Key | Default | Extra |
+---------+-------------+------+-----+---------+-------+
| lagnamn | varchar(10) | YES  |     | NULL    |       |
| poang   | int(2)      | YES  |     | NULL    |       |
+---------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

mysql> select * from lag;
+---------+-------+
| lagnamn | poang |
+---------+-------+
| lag 1   |     3 |
| lag 2   |     0 |
| lag 3   |     2 |
| lag 1   |     1 |
+---------+-------+
4 rows in set (0.00 sec)

mysql> select lagnamn,sum(poang) as summa
    -> from lag
    -> group by lagnamn
    -> order by summa desc;
+---------+-------+
| lagnamn | summa |
+---------+-------+
| lag 1   |     4 |
| lag 3   |     2 |
| lag 2   |     0 |
+---------+-------+
3 rows in set (0.00 sec)

mysql>

Mvh
/Ulf

  • Medlem
  • Stockholm
  • 2003-04-30 18:31

Tack för ditt svar men du missförstod mig lite.

Vad jag undrade var om jag kunde smita runt det där med att skapa en tabell för att spara ett lags poäng.
Alltså inte spara
lag 1: 3p (dvs vinst)

utan hellre spara:

lag1: 3mål
lag2: 2mål

och utifrån den informationen ge lag1 3p och lag2 0p ... utan att spara det i en egen tabell.
Klart man kan göra det, men kan man hämta hem den informationen i sorterad ordning?

Man kan nog hämta hem informationen och spara i någon form av array och hantera informationen utifrån det.

Tack ändå för ett ambitiöst och bra svar!

Det går bara fint att göra om man har en SQL-databas. Exemplet här nedanför är gjort i PostgreSQL, men med lite tur fungerar det kanske i MySQL även om man ju inte direkt kan påstå att den databasen ens är i närheten av att följa någon SQL-standard whatsoever...

Så här ser tabellen jag testade ut - som du kan se i resultatet lite längre ner stuvade jag in lite målsiffror på måfå i tabellen.

Table "test"
  Column  |  Type   | Modifiers 
----------+---------+-----------
 lag1_mal | integer | 
 lag2_mal | integer | 

Det här är SQL-satsen jag körde med:

SELECT *,
    (CASE WHEN lag1_mal > lag2_mal THEN '3'
          WHEN lag1_mal < lag2_mal THEN '0'
          ELSE '1'
    END) AS lag1_poang,
    (CASE WHEN lag2_mal > lag1_mal THEN '3'
          WHEN lag2_mal < lag1_mal THEN '0'
          ELSE '1'
    END) AS lag2_poang
FROM test;

Och så sist resultatet:

lag1_mal | lag2_mal | lag1_poang | lag2_poang 
----------+----------+------------+------------
        3 |        1 | 3          | 0
        2 |        1 | 3          | 0
        2 |        2 | 1          | 1
        1 |        2 | 0          | 3
(4 rows)

Som du ser gjorde jag ingen sortering eller sammanslagning av det totala antalet poäng, men det är i allra högsta grad möjligt att göra. Jag kände mig bara inte tillräckligt ambitiös idag

Sådana här operationer ger lätt ganska komplicerade SQL-satser, så det jag skulle rekommendera dig att göra är att dela upp allt i mindre delar. Det ger iofs aningen sämre prestanda om det är en kritisk applikation, men det är ofta bättre än att lägga ner en hel dag på att klura fram, testa och felsöka en enda gigantisk SQL-sats som ska göra allt på en gång. Tyvärr erbjuder ju MySQL ohyggligt dåliga sådana möjligheter (det är bl.a. därför jag skyr den databasen som pesten numera ), så kör du MySQL är det approachen med en enda kilometerlång SQL-sats som gäller...

  • Medlem
  • Stockholm
  • 2003-05-02 23:23

Aha!

CASE WHEN <> THEN <>;

nice!

Jag är nästan framme nu!
Kan fortfarande inte sortera efter vilket lag som har gjort flest mål? Men det här var klart en viktig del i det målet.

Gissar att jag kan göra en nästlad SELECT sats som jag binder till varje lag och i den nästlade satsen så har jag räknat ut poängen för just det laget.
Fast kan erkänna att jag i skrivande stund inte kommer på exakt hur det skulle kunna se ut...

Men tack som fasen Samuel K, du ledde in mig på helt rätt spår!

love this place!

Citat:

Skrevs ursprungligen av ivar
Aha!

CASE WHEN <> THEN <>;

nice!

Jag är nästan framme nu!
Kan fortfarande inte sortera efter vilket lag som har gjort flest mål? Men det här var klart en viktig del i det målet.

Gissar att jag kan göra en nästlad SELECT sats som jag binder till varje lag och i den nästlade satsen så har jag räknat ut poängen för just det laget.
Fast kan erkänna att jag i skrivande stund inte kommer på exakt hur det skulle kunna se ut...

Men tack som fasen Samuel K, du ledde in mig på helt rätt spår!

love this place!

Nu är jag trött men jag har för mig att man inte (mysql version < 4) kan göra select-satser inne i andra select-satser. I så fall får du köra med någon form av JOIN.

  • Medlem
  • Stockholm
  • 2003-05-03 10:49

WHAT!
Helt galet!!
Hela systemet jag bygger just nu använder nästlade satser.

Tills vidare utgår jag från att det måste gå

Jag kommer behöva använda mig utav två tabeller för det som jag beskrivit tidigare.

En som innehåller information om laget, kommer se ut ungefär så här:

lag_id *  (auto_increment)
namn  (varchar 40)
lag_farg (varchar 20)
hemsida (varchar 200)
kommentar (text)
senast_andrad (timestamp)

och sen en tabell som innehåller Matcher:

match_id *  (auto_increment)
datum (varchar 10)
tidpunkt (varchar 5)
hemma_lag (int  lag_id)
hemma_mal_halvtid (int)
hemma_mal_heltid (int)
borta_lag (int lag_id)
borta_mal_halvtid (int)
borta_mal_heltid (int)  
lamnat_WO (lag_id)
division (text)
serie (text)
kommentar (text)

Något i stil med det där.
Utifrån det där vill jag alltså skapa den klassiska resultat-tabellen.... (den med "gjorda mål", "insläppta mål", "poäng", "spelade matcher" osv).
För att skapa den så använder den sig av de två åvan.
Jag ser framför mig att man väljer ett lag i taget ifrån Lag, och för varje lag så går man igenom matcher och räknar fram värdena.

Appropå Samuels CASE upplysning åvan. Undra om jag inte behöver använda de för att räkna ut samtliga andra fält också då ibland är laget i fråga hemmalag och ibland borta.

SELECT *,
    (CASE WHEN hemma_lag = $lag THEN 'SUM(hemma_mal_heltid)'
          CASE WHEN borta_lag = $lag THEN 'SUM(borta_mal_heltid)'

    END) AS lag1_gjorda_mal
FROM ....

Skulle det se ut något i stil med åvan?

1
Bevaka tråden