avancerad SQL-sats

Tråden skapades och har fått 21 svar. Det senaste inlägget skrevs .
1
  • Medlem
  • Stockholm
  • 2003-10-03 00:38

Hej!

Behöver hjälp med en SQL-sats.
Ska nämligen hämta fram värden ur en resultat-tabell för att göra en fotbollstabell.

Tabellen har följande fält:

match_id (primary key)

hemma_lag (lag_id)
hemma_mal_halvtid
hemma_mal

borta_lag(lag_id)
borta_mal_halvtid
borta_mal

Om ett lag vunnit matchen får laget 2p om lagen spelar lika får de 1p vardera och annars vid förlust får man 0p.
Jag undrar om det går att räkna ut lags olika poänger och sortera efter det?

Vill du göra det med SQL:en?

Eller med PHP el motsvarande?

I mysql ser det ut något i stil med:

SELECT CASE 
WHEN hemma_mal > borta_mal THEN 2 WHEN hemma_mal = borta_mal THEN 1 ELSE 0 
END 
FROM [resultat_tabell] 
WHERE match-id = [ett eller annat];

Har inte testat om det här fungerar men skulle tro det. Annars får någon annan flika in

  • Medlem
  • Stockholm
  • 2003-10-03 12:12

Så här skrev Samuel K i en gammal tråd

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;

problemet är (som jag skrev i den tråden också) att jag kan ju inte sortera efter vilket lag som fått mest poäng. Det är ju åtta olika lag, inte två

Men den här metoden är väl ett steg i rätt riktning?

Måste man inte köra någon "GROUP BY lagNamn" och joina tabellen med Lag-tabellen ?
På något vänster måste jag ju få det att inte bli så att den räknar ut poängen för alla hemmalag och sen poäng och statistik för alla bortalag...

gimme more of your constructive ideas! :rolleyes:

  • Oregistrerad
  • 2003-10-03 12:42
Citat:

Skrevs ursprungligen av ivar
problemet är (som jag skrev i den tråden också) att jag kan ju inte sortera efter vilket lag som fått mest poäng. Det är ju åtta olika lag, inte två

Varför skulle man inte kunna sortera efter hur många poäng laget har fått, om man har fler än två lag?

  • Medlem
  • Stockholm
  • 2003-10-03 13:04

För att man använder sig av två fält? lag1_poang och lag2_poang ?

Är jag ute och cyklar?

Ska man hämta fram infot för två lag hela tiden och fylla på i en php-array? Kan man söka i arrayen och lägga till info för specifika arrayfält?

edit: ja, man kan söka i en array

Har svårt att förstå vad du vill ha - är det något i stil med detta:

SELECT [lagnamn/id] ,
CASE WHEN hemma_mal > borta_mal THEN 2 
WHEN hemma_mal = borta_mal 
THEN 1 
ELSE 0 
END 
AS poang
FROM [tabellen] ORDER BY poang DESC
  • Medlem
  • Stockholm
  • 2003-10-03 13:22
Citat:

Skrevs ursprungligen av scooterbabe
Har svårt att förstå vad du vill ha

Jag förstår det...
citerar vad jag skrivit i en annan tråd

Citat:

Skrevs ursprungligen av ivarJag måste göra en flerdimensionell array.. det kommer nog lösa sig, kikat på det förut men aldrig gjort det.

Kommer för varje lag behöva spara:
1. hur många spelade matcher
2. hur många gjorda mål
3. hur många insläppta mål
4. hur många vunna matcher
5. hur många oavgjorda matcher
5. hur många förlorade matcher
6. hur många poäng laget har

Min tidigare lösning på det här problemet var att ha en tabell i sql där jag sparade alla dessa värden. Nu vill jag göra en ordentligare lösning där värdena räknas fram och alltid är aktuella. Man ska även kunna välja att "Visa statistik för laget efter x spelade matcher" där x är allt ifrån 1 t.o.m. lagets antal spelade matcher.

Måste man göra en flerdimensionell array kanske... Fungerar kanske inte att göra en avancerad MySQL-sats?

Senast redigerat 2003-10-03 14:15

Det här bör fungera:

SELECT lag_id, sum(poang) AS poang FROM
  (SELECT hemma_lag AS lag_id,
                (CASE WHEN hemma_mal > borta_mal THEN 2
                      WHEN hemma_mal = borta_mal THEN 1
                      ELSE 0
                 END) AS poang
   FROM matcher
   UNION ALL
   SELECT borta_lag AS lag_id,
                (CASE WHEN borta_mal > hemma_mal THEN 2
                      WHEN borta_mal = hemma_mal THEN 1
                      ELSE 0
                 END) AS poang
   FROM matcher) AS lag_poang
GROUP BY lag_id
ORDER BY sum(poang) DESC;

Nu har jag iofs inte tagit mig tid att kolla upp vilka roligheter mysql kan tänkas åstadkomma med SQL-satsen ovan, men de flesta något så när SQL92-kompatibla databashanterare ska klara det bara fint.

från och med vilken version av mysql är det man kan göra subselects?

  • Medlem
  • Österåker
  • 2003-10-03 15:53
Citat:

Skrevs ursprungligen av Khedron
4.1

Stämmer bra, men 4.1 är inte släppt ännu, så vitt jag vet. Bara som beta. Dessutom tror jag det var en del tråkiga begränsningar i 4.1 som inte kommer vara fixade förräns i senare releaser, tyvärr. Men det mesta som går att göra med subselects går att göra (krångligare) med JOINS.

Citat:

Skrevs ursprungligen av scooterbabe
Stämmer bra, men 4.1 är inte släppt ännu, så vitt jag vet. Bara som beta. Dessutom tror jag det var en del tråkiga begränsningar i 4.1 som inte kommer vara fixade förräns i senare releaser, tyvärr. Men det mesta som går att göra med subselects går att göra (krångligare) med JOINS.

Kommer subselect-begränsningarna alltså fortfarande att ligga kvar även i 4.1? Jag fick intrycket när jag skumläste igenom listan över sådant som skulle fixas från 4.0 att det skulle lösas i 4.1 (som iofs knappt ens var i alfaversion då). Men mysql är ju rätt bra på vaporware i övrigt också, såg för ett tag sedan att de stolt utannonserade att vyer skulle komma i version 6.0. Heja...

Men det är ju oftast som du säger, att mycket av det man löser med subselects kan göras med join-satser (som iofs då kan bli rätt otäcka historier). Däremot tror jag inte att det går att göra med exemplet här ovan, eftersom det är en nästlad union-sats. Eller?

Du kanske har flera fält i tabellen än du redovisade här, men skulle inte "omgång" vara bra att ha med. Dvs, så att man ser till vilken omgång ett resultat hör?

Sedan, trots att jag inte betvivlar att det går att konstruera hur håriga select-satser i SQL som helst, vad är poängen..? Om det är statistiskt material du skall ta fram tycker jag du bör iterera fram det i ditt favoritprogrammeringsspråk. Låt säga att det är PHP, du skall använda för att implementera affärslogiken (och presentationen) i. Det blir fantastiskt mycket mera lättbegripligt, och lättare att underhålla då.

Sedan, min lilla käpphäst... Jag tycker att tabeller, fält och variabler och kommentarer skall vara på engelska. Sorry, men det är mitt privata lilla korståg.

Citat:

Skrevs ursprungligen av ace4711
Sedan, trots att jag inte betvivlar att det går att konstruera hur håriga select-satser i SQL som helst, vad är poängen..?

Bortsett från prestanda (som knappast kan sägas vara en viktig fråga i den här sortens applikation) finns det egentligen inte så stora fördelar med att lägga in über-håriga sql-satser i koden. Den sortens lösningar urartar ganska lätt till spaghettikod.

Om man däremot har en lite bättre databashanterare med stöd för vyer tycker jag att det finns en del rätt stora fördelar. Vill man, säg, ha en lista med de tre bästa lagen kan man skapa en vy ("virtuell tabell" som skapas dynamiskt utifrån en sql-sats) som sköter den biten. Då behöver man bara använda den håriga SQL-satsen en enda gång, d.v.s. när man skapar vyn, och sedan kommer man åt den med en trivial "SELECT * FROM..."-sats. Då håller man koden ren från både gigantiska SQL-satser och överflödiga iterationslösningar. Det förutsätter ju iofs att man lärt sig en del SQL, men det är en ansträngning som jag tycker är klart värd att göra

Citat:

Skrevs ursprungligen av Samuel K
Kommer subselect-begränsningarna alltså fortfarande att ligga kvar även i 4.1? Jag fick intrycket när jag skumläste igenom listan över sådant som skulle fixas från 4.0 att det skulle lösas i 4.1 (som iofs knappt ens var i alfaversion då).

Som jag förstått det skall det lanseras på bred front i o m 4.1, men jag har för mig att det även var en del viktiga delar av subselectdelen som inte skulle komma förräns senare, och med tanke på hur länge mysql-versionerna är alfa så lär det ju dröja. Men jag kan mixat ihop det med fulltextsökningarna eller nåt.

I övrigt älskar jag manualen till mysql, och sitter och är glad över att indexeringen av några kolumner i min mastodontdatabas jag arbetar med f n gjorde att en tokfet join-union över bl a en tabell med över 10.000 poster sjönk i tid från ca 6,5 min till under 10 sekunder!

Inte för att den någonsin skall användas på det sättet, men man måste ju testa i benchmarkingsyfte, eller hur?

  • Medlem
  • Stockholm
  • 2003-10-03 21:39
Citat:

Skrevs ursprungligen av ace4711
[...]

Sedan, min lilla käpphäst... Jag tycker att tabeller, fält och variabler och kommentarer skall vara på engelska. Sorry, men det är mitt privata lilla korståg.

Jag tycker det är lite "löjligt" att inte använda sitt "vardagsspråk". Skrev själv allt på engelska förut men efter att ha gått två kurser i programmeringsmetodik så har jag börjat skriva variabelnamn på svenska... mycket svengelska förekommer dock

Citat:

Skrevs ursprungligen av ivar
Jag tycker det är lite "löjligt" att inte använda sitt "vardagsspråk". Skrev själv allt på engelska förut men efter att ha gått två kurser i programmeringsmetodik så har jag börjat skriva variabelnamn på svenska... mycket svengelska förekommer dock

Samma här, försöker hålla mig till svenska men en del variabelnamn låter så fåniga att det ofta blir svengelska...

Citat:

Skrevs ursprungligen av ivar

Min tidigare lösning på det här problemet var att ha en tabell i sql där jag sparade alla dessa värden. Nu vill jag göra en ordentligare lösning där värdena räknas fram och alltid är aktuella. Man ska även kunna välja att "Visa statistik för laget efter x spelade matcher" där x är allt ifrån 1 t.o.m. lagets antal spelade matcher.

Måste man göra en flerdimensionell array kanske... Fungerar kanske inte att göra en avancerad MySQL-sats? [/B]

Nu tycker jag visserligen att det är bättre med en tabell där poäng, mål mm är summerade men om du inte tycker den är ordentlig så föreslår jag följande:

Istället för att krångla till det med en SQL-sats som ändå kanske är mer än mySQL klarar så gör följande: Läs upp alla poster från databasen till php, loopa igenom värdena och summera per lag i en ny array.
Använd en array med nycklar där lag_id är nyckel.
Därefter sorterar du den array:en med usort och en egen definierad sorteringsfunktion.

Joakim

  • Medlem
  • Stockholm
  • 2003-10-06 11:16
Citat:

Skrevs ursprungligen av jocked
Nu tycker jag visserligen att det är bättre med en tabell där poäng, mål mm är summerade men om du inte tycker den är ordentlig så föreslår jag följande:

Istället för att krångla till det med en SQL-sats som ändå kanske är mer än mySQL klarar så gör följande: Läs upp alla poster från databasen till php, loopa igenom värdena och summera per lag i en ny array.
Använd en array med nycklar där lag_id är nyckel.
Därefter sorterar du den array:en med usort och en egen definierad sorteringsfunktion.

Joakim

Jag vill inte ha värdena skrivna i en tabell för de minskar funktionaliteten på sidan. Tänkte ha en jumpMenu() via vilken man kan välja att visa hur tabellen såg ut efter tex 5 spelade matcher.

Dock har jag inte arbetat med arrayer särskilt mycket alls i php och visar det sig att det är segt och långsamt måste jag återgå till att köra med en statistik-tabell med info som räknas ut ifrån de andra tabellerna.

Om jag inte riktigt förstår så hoppas jag det är ok att jag återkommer med fler "grundläggande" frågor kring flerdimensionella arrays och egna sorteringsfunktioner.

Mycket tacksam!
Jätte bra inlägg, tack!!

mvh
ivar

En annan sak som är bra med en iterativ lösning i ditt programmeringsspråk är att du kan hantera Walk-Over och andra specialfall. Min erfarenhet av korpspel i innebandy är att det dessvärre blir nån WO-match per säsong. Det kan bli ännu omöjligare att hantera med en hårig SQL-sats än med PHP. Till sist måste jag också varna för den tickande prestandabomb som finns med komplicerade SQL-satser. Det är mycket svårt för en icke-häxmästare att se på en SQL-sats hurvida den tar exponitiellt tid i förhållande till antalet poster. En iteration över posterna i ett programmeringsspråk kan enkelt fås att utföras med linjärt förhållande mellan tidsåtgång och antal poster.

  • Medlem
  • Stockholm
  • 2003-10-06 12:15

Ok, bra.

Tack för ännu ett bra inlägg

... och stickspåret med engelska eller svenska i programering.

Jag tycker inte det är "kaxigt" eller störigt att använda engelska i all kod jag skapar. Inte ens i sådan kod jag skriver för min egen del. För det första så tycker jag det blir mycket konstigt när kontrollstrukturer och själva programmeringsspråket är på engelska och resten är på svenska. Det blir dessutom totalkollrigt när man inte kan använda ÅÄÖ. Men, det största skälet för min del är att man aldrig vet när någon annan skulle vilja titta på ens kod. Ibland när jag söker på webben efter relevant kod så hittar jag något. Det kanske är nån som har gjort en egen idrottstabellslösning i MySQL och PHP som jag skulle vilja bygga vidare på... Så, visar det sig att variabelnamn och tabeller är skrivna på slovenska. Nästan omöjligt för mig att jobba vidare.

1
Bevaka tråden