För mina webbspels resultathantering (än så länge bara tre spel) har jag följande kod:
$getGamePrefs = "SELECT PlayerParameters.pName, PlayerScoresPB.pScore FROM PlayerParameters INNER JOIN PlayerScoresPB ON PlayerParameters.pID=PlayerScoresPB.pID";
vilket genererar alla spelarnamn som har minst ett resultat i något spel Det resulterar i att samma namn dyker upp flera gånger - en gång för varje spel spelaren har resultat i och det är inte riktigt vad jag är ute efter.
Det jag vill ha hjälp med i första hand är hur jag kan förändra min kod till att få fram alla namn som saknar resultat.
I andra hand vill jag gärna veta hur jag gör för att få fram olika varianter på villkor för de saknade resultaten - se nedan:
Jag vill få fram alla namn som:
saknar resultat i något av spelen.
saknar resultat i ett specifikt spel.
saknar resultat i ett ospecificerat spel.
saknar resultat i ett bestämt antal ospecificerade spel.
saknar resultat i ett bestämt antal specifika spel.
select pp.pname
from playerParameters pp
where pp.pid
not in ( select ps.pid
from playerScoresPB ps )
De som saknar resultat i ett specifikt spel:
select pp.pname
from playerParameters pp
where pp.pid
not in ( select ps.pid
from playerScoresPB ps
inner
join <game table name> g
on s.<game id> = g.<id>
where g.<name> = "game's name" )
För att sakna resultat i fler spel än game's name, lägger du till or "game's 2 name" efter.
De som saknar resultat i ett ospecificerat antal spel:
select pp.pname, count(distinct ps.<game id>)
from playerParameters pp
left
join playerScoresPB ps
on pp.pid = ps.pid
group
by pp.pname
having count(distinct ps.<game id>)
< ( select count(*)
from <game table name> )
Den senare kan du modifiera till att bestämma ett specifikt antal spel genom att byta < mot =, och lägga till +N efter having count(...) där N är antalet spel som resultat skall saknas i. För att sakna resultat i, säg, tre spel:
select pp.pname, count(distinct ps.<game id>)
from playerParameters pp
left
join playerScoresPB ps
on pp.pid = ps.pid
group
by pp.pname
having count(distinct ps.<game id>)+3
= ( select count(*)
from <game table name> )
Wow, tack - det här var ju verkligen heltäckande. Nu har jag och jobba med... fast...
Det är bara en liten sak som jag funderar över och det är förkortningarna pp och ps du har i dina exempel.
Vad betyder de?
Först trodde jag du inte ville skriva ut tabellnamnen, men sen såg jag att de fanns med de också, t ex i "from playerParameters pp". Det skulle ju då bli "from playerParameters playerParameters" vilket jag inte känner igen. Sen dök en annan tanke upp - att de skulle vara någon förkortad version av "playerParameters AS pp" men i så fall borde ovan exempel bli "from pp pp". Ridå!
Hoppas du kan hjälpa mig lite mer på traven så jag verkligen får nytta av den hjälp du gett mig hittills. Jag är väldigt sugen på att ta tag i exemplen, men fastnat. Tack på forehand!
..och tack för välkomnandet! Det är suveränt att ha den här möjligheten. Hoppas jag bara kan bjuda tillbaka med kunskap längre fram.
Troligtvis kallar du inte på "pp" innan det sätts som alias. SQL-frågan bearbetas först av DBMS där den joinar tabeller och utför villkorssatser; SELECT görs sist av allt.
Fenomenet med nästlade SELECT-satser kallas subqueries. Den utförs innan den omslutande frågan och returnerar mängd av information som är till nytta för den yttre. Det är svårt att beskriva hur man skall tänka. Klart är att du får överge tillvägagångssätt inom ex. PHP, för att i stället fundera i tabeller och mängder.
Mer - och utförligare - beskrivningar torde forumets SQL-gurus kunna bidra med.
Nu har jag läst in mig på "subqueries" och förstår vad de är till för och hur de används. Det behövs lite jobb med tester för att min användning av dem ska sitta, men det får ta sin tid. Nu vet jag i alla fall grunderna så pass att jag kan gå vidare med dina exempel.
Då tänkte jag bara fråga, för att lära mig mer, hur man kan lösa första exemplet utan "subqueries"? Jag förutsätter att det går att lösa med en JOIN-sats.
SELECT pP.pName
FROM playerParameters AS pP
WHERE pP.pID
NOT IN (SELECT pS.pID
FROM playerScoresPB AS pS)
Om jag lär mig skillnaden kan jag lättare förstå när jag ska använda respektive metod.
(Jag kör med AS ett tag till tills det sitter, sen kan jag börja med den kortare varienten.)
Ok, nu har jag läst in mig mer på Subqueries och JOIN-satser så jag förstår bättre hur de fungerar och hur jag ska använda dem. Jag har börjat testa lite mer och försöker använda den koden du som ger de namn som saknar resultat i ett specifikt spel (alternativ två i din uppräkning).
Jag har "snyggat" till den så att den känns enklare för mig att använda och fyllt i de uppgifter du inte hade tillgång till (InGameParameters och variabeln för valt spel: $GameID. Så här blev det då:
$gTmp01 = "SELECT PP.pName, PP.pID
FROM PlayerParameters AS PP
WHERE PP.pID NOT IN (SELECT PS.pID
FROM PlayerScoresPB AS PS INNER JOIN InGameParameters AS IgP
ON PS.gID = IgP.gID
WHERE InGameParameters.gID = $GameID)";
Jag får negativt svar på mysql_query($gTmp01).
Kan du hitta några fel i koden?
Sen har jag en till liten fråga: Vilket är bäst - att skriva hela SELECT-satsen på en rad eller dela upp den som ovan? Vad är brukligt? Fördelar/nackdelar med de två sätten?
Vad betyder "negativt svar"? Om du kör SQL-frågan på en php-sida, se till att du får ut alla felmeddelanden du behöver för felsökning. Prova också att köra frågan direkt i MySQL / via ex. phpmyadmin.
Eventuellt kan ett problem vara att du i WHERE i din subquery har skrivit InGameParameters.gID, trots att du gett tabellen aliaset IgP. Byt till aliasnamnet istället.
Sen har jag en till liten fråga: Vilket är bäst - att skriva hela SELECT-satsen på en rad eller dela upp den som ovan? Vad är brukligt? Fördelar/nackdelar med de två sätten?
Jag bytte till IgP och då fungerade det! :-)
Tackar tackar!
Ang. det negativa svaret så avsåg jag svaret: "Det gick inte att hämta information från databasen!" jag fick från mysql_query-frågan jag använder för att hämta fram resultet:
$GamePrefs = mysql_query($getGamePrefs) or die("Det gick inte att hämta information från databasen!");
Ang. det negativa svaret så avsåg jag svaret: "Det gick inte att hämta information från databasen!" jag fick från mysql_query-frågan jag använder för att hämta fram resultet:
$GamePrefs = mysql_query($getGamePrefs) or die("Det gick inte att hämta information från databasen!");
Ok. Ta för vana att alltid ta hand om felet från MySQL.
..... or die(mysql_error());
mvh
265 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2