Toplijstje maken
Ik heb een database gevuld met transacties. Ik wil hiervan een toplijstje maken van degene die het meest heeft verkocht, hieronder een voorbeeld. De echte database gevuld is met meer dan 800 pagina's.
Nu is het nog zo:
Jasper
Pieter
Jasper
Pieter
Pieter
Henk
Pieter
Henk
Hier moet een toplijst van gemaakt worden, zoiets:
Pieter
Jasper
Henk
Dit heb ik nu (uitkomst ziet eruit als voorbeeld 1, moet voorbeeld 2 worden):
Quote:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
$con=mysqli_connect("--","--","--","--");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM shop_transactions");
while($row = mysqli_fetch_array($result))
{
echo $row['Player1'];
echo "</br>";
}
?>
$con=mysqli_connect("--","--","--","--");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM shop_transactions");
while($row = mysqli_fetch_array($result))
{
echo $row['Player1'];
echo "</br>";
}
?>
Alvast bedankt.
Gewijzigd op 21/05/2013 10:15:17 door Pix Pixer
Code (php)
1
2
3
4
2
3
4
SELECT player1, COUNT(*) AS num_transactions
FROM shop_transactions
GROUP BY player1
ORDER BY num_transactions DESC
FROM shop_transactions
GROUP BY player1
ORDER BY num_transactions DESC
En dit is natuurlijk de query die je moet gebruiken om de spelers op te halen, de rest kan je laten zoals je al had.
Erwin H op 21/05/2013 10:23:52:
Dat werkt top, hartelijk bedankt! Enig idee hoe ik nu zorg dat er maximaal 5 resultaten komen? Veel dank.
LIMIT 5
Erwin H op 21/05/2013 10:28:13:
LIMIT 5
Erg bedankt. Laatste vraag: hoe kan ik zorgen dat ik 1 resultaat er uit laat? Dit is de naam van mij namelijk en deze moet eruit.
SELECT player1, COUNT(*) AS num_transactions
FROM shop_transactions
WHERE player1 != 'henk'
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
Reshad F op 21/05/2013 10:31:21:
Volgens mij zoiets ( ik neem even aan dat je henk heet maar je moet daar dus je eigen naam invullen )
SELECT player1, COUNT(*) AS num_transactions
FROM shop_transactions
WHERE player1 != 'henk'
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
SELECT player1, COUNT(*) AS num_transactions
FROM shop_transactions
WHERE player1 != 'henk'
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
Dat werkt inderdaad, wist niet dat het zo kon. Weer wat geleerd.
Dank voor de hulp.
En dan bij voorkeur niet '!=' als operator gebruiken, maar '<>'.
Erwin H op 21/05/2013 10:34:14:
En dan bij voorkeur niet '!=' als operator gebruiken, maar '<>'.
Waarom precies? Ben benieuwd.
<> is de standard in SQL en is altijd in de specificaties zo geweest. != is over komen waaien uit programmeertalen wordt door een aantal database systemen inmiddels ondersteund, maar niet door alle. In MySQL zal het overigens gewoon werken (in elk geval MySQL 5, eerdere versies weet ik niet 100% zeker), maar je zal maar eens je code willen overzetten op een systeem dat die operator niet kent. Gebruik je <> dan zit je altijd goed.
Erwin H op 21/05/2013 10:38:21:
<> is de standard in SQL en is altijd in de specificaties zo geweest. != is over komen waaien uit programmeertalen wordt door een aantal database systemen inmiddels ondersteund, maar niet door alle. In MySQL zal het overigens gewoon werken (in elk geval MySQL 5, eerdere versies weet ik niet 100% zeker), maar je zal maar eens je code willen overzetten op een systeem dat die operator niet kent. Gebruik je <> dan zit je altijd goed.
Bedankt!
Het script pakt uit de database Player2 maar 1x. Hierdoor kijkt hij dus hoeveel unieke spelers er uit de shop hebben gekocht. Zou dit nog met een aanpassing in de query kunnen? Ik heb gezocht op Google maar kon het maar niet uitvinden.
Bedankt.
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
)
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
)
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
Dit selecteert dus alle unieke player1, player2 combinaties uit de database en voert over die subset de rest van de query uit.
De uitgezonderde speler heb ik meteen in de subquery opgenomen omdat je de rest van de query daar toch niet overheen hoeft laten te gaan.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
$con=mysqli_connect("XX","XX","XX","XX");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'ADMIN SHOP'
)
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
");
echo "<b>Best verkopende shops:</b>";
echo "<i></br>In de afgelopen 7 dagen</i>";
echo "</br>";
echo "<ol id='trala'>";
while($row = mysqli_fetch_array($result))
{
$uitkomst = $row['Player1'];
echo "<li>$uitkomst</li>";
echo "";
}
echo "</ol>";
?>
$con=mysqli_connect("XX","XX","XX","XX");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'ADMIN SHOP'
)
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
");
echo "<b>Best verkopende shops:</b>";
echo "<i></br>In de afgelopen 7 dagen</i>";
echo "</br>";
echo "<ol id='trala'>";
while($row = mysqli_fetch_array($result))
{
$uitkomst = $row['Player1'];
echo "<li>$uitkomst</li>";
echo "";
}
echo "</ol>";
?>
Op dit moment krijg ik deze error;
Warning: mysqli_fetch_array() expects parameter 1 to be mysqli_result, boolean given in /var/www/toplist/index.php on line 38
Dit is line 38: while($row = mysqli_fetch_array($result))
Gewijzigd op 28/05/2013 09:21:05 door Pix Pixer
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
) a
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
) a
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
En dus misschien ook tijd om je foutafhandeling wat te verbeteren....
Gewijzigd op 28/05/2013 09:31:53 door Erwin H
Erwin H op 28/05/2013 09:31:32:
klopt, sorry, een subquery heeft altijd een alias nodig:
En dus misschien ook tijd om je foutafhandeling wat te verbeteren....
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
) a
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
) a
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
En dus misschien ook tijd om je foutafhandeling wat te verbeteren....
Volgens mij werkt die nu inderdaad goed. Maar even voor de zekerheid, dit wil ik ermee:
Database:
Henk koopt 1 patat van Piet
Henk koopt 1 patat van Piet
Henk koopt 1 patat van Piet
Henk koopt 1 patat van Piet
Pieter koopt 1 kroket van Jasper
Pieter koopt 1 kroket van Jasper
Henk koopt 1 patat van Jasper
In het toplijstje moet ''henk'' dus eigenlijk maar 1x patat kopen van Piet en 1 kroket van Jasper om zo misbruik te voorkomen. Maar als henk 1x een patat koopt bij
Piet dan moet hij Henk zijn transactie nog wel meetellen als hij bij iemand anders koopt.
Wil je dat onderscheid wel maken, dan voeg je de kolom met het product toe aan de SELECT DISTINCT in de subquery.
Gewijzigd op 28/05/2013 10:06:25 door Ger van Steenderen
Ger van Steenderen op 28/05/2013 10:06:04:
SELECT DISTINCT zorgt er voor dat er geen duplicaat rijen geselecteerd op de kolommen die in de select lijst staan. In Erwins voorbeeld maakt het dus niet wat Henk bij Piet koopt, de combinatie Henk, Piet wordt maar één keer geselecteerd.
Wil je dat onderscheid wel maken, dan voeg je de kolom met het product toe aan de SELECT DISTINCT in de subquery.
Wil je dat onderscheid wel maken, dan voeg je de kolom met het product toe aan de SELECT DISTINCT in de subquery.
SELECT player1, COUNT(*) AS num_transactions
FROM (
SELECT DISTINCT player1, player2
FROM shop_transactions
WHERE player1 <> 'henk'
WHERE ItemID = 264
) a
GROUP BY player1
ORDER BY num_transactions DESC
LIMIT 5
Zoiets?
Henk koopt 1 patat van Piet
Henk koopt 1 patat van Piet
Henk koopt 1 kroket van Piet
Pieter koopt 1 kroket van Jasper
Pieter koopt 1 kroket van Jasper
Henk koopt 1 patat van Jasper
SELECT DISTICT player1, player2 FROM shop_transactions geeft:
Henk, Piet
Pieter, Jasper
Henk, Jasper
Verander je die naar:
SELECT DISTINCT player1, player2, item_id FROM shop_transactions krijg je:
Henk, Piet, patat
Henk, Piet, kroket
Pieter, Jasper, kroket
Henk, Jasper, patat
Een (sub)query kan overigens altijd maar 1 WHERE bevatten