2 lijsten op basis van 2 key velden, 1 query

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Alfred McGuffin

Alfred McGuffin

31/01/2015 10:13:14
Quote Anchor link
Hallo

Wie kan me op weg helpen met het volgende.
In een sql tabel staat:

velden:
id,username, timestamp, color
1, user2, 12:00, blauw;
2, user1, 12:01, groen;
3, user2, 12:05, purper;
4, user1, 12:11, wit;

wat is de meest efficiëntste manier om een lijst te 'echo-en' met éérst alle waarden van user1 en daarna alle van user 2
dus groeperen en dan 1 voor 1 tonen
De grove manier is om 2 maal achter elkaar een query te doen,
dus in het geval alle records om van elke user te vinden
$query = mysql_query ('SELECT *
FROM table
WHERE user = "User1"
ORDER BY id DESC
');

while ($row = mysql_fetch_assoc($query))
{
echo $row['User1'].$row['timestamp'].$row['color'];
}

hoe kan dat met 1 query?


2e vraag: wat is de handigste manier om van beide users het laatste toegevoegde record te krijgen
dus in het geval alle records om van elke user te vinden, 2 maal een query
$query = mysql_query ('SELECT *
FROM table
WHERE user = "User1"
ORDER BY id DESC
LIMIT 1
');

while ($row = mysql_fetch_assoc($query))
{
echo $row['User1'].$row['timestamp'].$row['color'];
}

maar wat is de meest elegantste, in 1 query?

dank jullie
m
Gewijzigd op 31/01/2015 10:29:13 door Alfred McGuffin
 
PHP hulp

PHP hulp

26/04/2024 17:08:45
 
Frank Nietbelangrijk

Frank Nietbelangrijk

31/01/2015 11:18:01
Quote Anchor link
Als eerste zou het beter zijn om username te vervangen door user_id.

Ik ga er hierbij van uit dat je een tabel users hebt. Indien je die niet hebt zou ik willen adviseren om die aan te maken.

Dan blijft het bij jouw eerste vraag een kwestie van sorteren op de juiste volgorde en dat wijkt niet veel af van datgene er al staat:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
SELECT *
FROM table
ORDER BY username ASC, id DESC


Tweede vraag:
Hiervoor heb je dan een aggregate functie nodig: MAX() icm met een GROUP BY

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
SELECT MAX(id) AS max, username, ...
FROM table
GROUP BY username
ORDER BY id DESC
Gewijzigd op 31/01/2015 11:30:41 door Frank Nietbelangrijk
 
Alfred McGuffin

Alfred McGuffin

31/01/2015 11:33:08
Quote Anchor link
ah dat is al een heel stuk duidelijker
2e antwoord kom ik uit, dank

over de 1e:
hoe krijg ik 2 lijsten?
m.a.w. ná ales records van de ene user, komt een witregel (<p> oid) en dan alles van de volgende gebruiker

dank je wel
Gewijzigd op 31/01/2015 11:33:45 door Alfred McGuffin
 
Frank Nietbelangrijk

Frank Nietbelangrijk

31/01/2015 11:47:31
Quote Anchor link
Dat zou je met een kleine truc in je while lus kunnen oplossen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php
echo '<p>';

$username ='';
while($row = mysql_fetch_assoc($query))
{

    if($row['username'] != $username) {
        if($username != '') { // zo wordt de eerste keer overgeslagen
            echo '</p><p>';
        }

        $username = $row['username'];
        echo $row['username'] . ': ';
    }

    echo '<br>' . $row['max'];
}


echo '</p>';
?>
Gewijzigd op 31/01/2015 11:57:42 door Frank Nietbelangrijk
 
Alfred McGuffin

Alfred McGuffin

31/01/2015 12:17:50
Quote Anchor link
ja! dat is waar ook
veel dank!!

en, als ik je nog 1 vraag mag stellen, volgens mij ben ik er dan helemaal uit
hoe zou ik boven elke lijstje de username van die lijst ge-echoed krijgen?
 
- SanThe -

- SanThe -

31/01/2015 12:23:22
Quote Anchor link
Dat gebeurt toch al op regel 12 van Frank.
 
Frank Nietbelangrijk

Frank Nietbelangrijk

31/01/2015 13:26:39
Quote Anchor link
Had hem nog even aangepast misschien heeft Alfred dat gemist.
 
Thomas van den Heuvel

Thomas van den Heuvel

31/01/2015 14:31:45
Quote Anchor link
Als je per sé maar 1 query wilt gebruiken, kun je er ook voor kiezen om alles eerst in een "datastructuur" (een array) te zetten. Daarmee kun je het sorteerprobleem (deels) naar PHP verplaatsen.

Daarnaast zou het inderdaad beter zijn als je een user id zou gebruiken in plaats een user name. Daarbij werd er waarschijnlijk wel vanuit gegaan dat deze kolom is geïndexeerd. Veel hangt af (eigenlijk zou het verhaal hiermee moeten beginnen) van hoe je databasestructuur is opgezet - is deze opgezet met de InnoDB of de MyISAM engine?

Het (grote) voordeel van InnoDB ten opzichte van MyISAM is dat je hierin foreign keys (en dit impliceert weer het gebruik van indexen) en transacties kunt gebruiken. Een voordeel van MyISAM is dat je hiermee fulltext-searches kunt uitvoeren.

De eerste stap voor het efficiënt (gaan) uitvoeren van queries is een verkenning van je databasestructuur. Op grond daarvan besluit je of de huidige vorm geschikt is om snel op bepaalde kolommen te kunnen zoeken of sorteren. Vervolgens kun je besluiten of kolommen indexen nodig hebben of dat je je query zo bouwt, dat deze gebruik maken van de reeds aanwezige optimalisaties.
 
Alfred McGuffin

Alfred McGuffin

01/02/2015 11:13:06
Quote Anchor link
Jullie hebben me geweldig geholpen!
Het koste nog wat prakkiseren maar het is gelukt (veel van van geleerd!)
Het werkt precies zoals ik zou willen
Veel dank!!

@thomas
over de array daar heb je gelijk in.
dat heb ik nu ook gedaan
mag k jou of anderen daar wat over vragen..
ik heb nu keurige rijtjes met alle data van user1 en user2
hoe haal ik het laatste record van elke user naar voren?
oftewel de laatste key/value combi voordat de key een andere value krijgt.
uit het eerder voorbeeld (nu gesorteerd op 'user' en 'id' zoek ik een manier om id 4 en 3 bijvoorbeeld in 2 variabelen te zetten om elders te gebruiken
id,username, timestamp, color
2, user1, 12:01, groen;
4, user1, 12:11, wit; <==laatste van user1: $user1_latest_timestamp
1, user2, 12:00, blauw;
3, user2, 12:05, purper; <==laatste van user2: $user2_latest_timestamp

dank je
a
Gewijzigd op 01/02/2015 11:18:35 door Alfred McGuffin
 
Thomas van den Heuvel

Thomas van den Heuvel

01/02/2015 12:49:41
Quote Anchor link
Quote:
hoe haal ik het laatste record van elke user naar voren?

Als je alle gegevens ophaalt? Dat weet je pas als deze verandert. Je zou de "huidige" user bij kunnen houden in een variabele. En als die verschilt van het zojuist opgehaalde user id dan weet je dat deze is veranderd. Er vanuitgaande dat je al op user id sorteert, anders* kan de user mogelijk op elke regel veranderen.

Of ik begrijp niet precies wat je bedoelt? Wil je dat je queryresultaat enkel de laatste entry van een user bevat?

EDIT: Ah, het laatste dus. Frank had hierboven die vraag al beantwoord denk ik (MAX icm GROUP BY). Geeft dat niet het gewenste resultaat?
Gewijzigd op 01/02/2015 12:58:16 door Thomas van den Heuvel
 
Alfred McGuffin

Alfred McGuffin

01/02/2015 13:06:58
Quote Anchor link
Uitleggen ben ik geen ster :)
Ik heb nu , met hulp van Frank, vanuit 1 query 2 lijstjes:

user1
12:01 - groen;
12:03 - rood
12:11 - wit

user2
12:00 - blauw;
12:02 - groen
12:05 - paars

so far so good
Stel, 2 personen moeten een aantal gekleurde knoppen indrukken.
Weinig geavanceerd, maar werkt wel, haal ik de eerste keer dat de pers. een knop naar boven met

$record_count = 0;
while ($row = mysql_fetch_assoc($query)) {
$record_count += 1;
if($record_count == 1) {
echo $row['username'];
}
if($row['username'] != $username) {
$user = $row['username'];
echo $row['username'];
}
echo $row["timestamp"].', '.$row["color"].'),';
}



verderop heb ik nodig hoe laat user1 de láátste keer een knop indrukte en welke kleur (nl, 12:11 - wit)
idem voor de laatste knop van user2
kort gezegd heb ik van elke user de eerste en tijd nodig

ik zit nu een tijdje te puzzelen maar kwartje valt niet
Gewijzigd op 01/02/2015 13:40:37 door Alfred McGuffin
 
Thomas van den Heuvel

Thomas van den Heuvel

01/02/2015 14:30:57
Quote Anchor link
Het hangt er een beetje vanaf welke informatie je precies wilt.

Wil je zowel een lijst van alle entries van alle users en tevens (apart uitgelicht) de meeste recente tijd / kleur van een user

of

Wil je uitsluitend de laatste tijd / kleur per user?

Als je "alles" wilt is het wellicht makkelijker om alles eerst in een array-structuur te kieperen en in te delen op user id. Zo'n "datastructuur" is waarschijnlijk ook overzichtelijker dan dat je alles on-the-fly probeert te bepalen binnen een while-loop waarin je je resultaten ophaalt. Voorbeeld: je hebt je resultaten in het array $userData geladen met de volgende structuur:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
$userData
= array(
    1 => array(
        'entries' => array(
            array('time' => '...', 'color' => 'red'),
            array('time' => '...', 'color' => 'green'),
            array('time' => '...', 'color' => 'blue'),
            // etc.
        ),
    ),

    2 => array(
        // etc.
    ),
);


// first user
$user = $userData[1];
$lastEntryIndex = count($user['entries']) - 1; // mss ook even controleren of er uberhaupt entries zijn...

// color of last entry

echo $user['entries'][$lastEntryIndex]['color'];
?>



Je aanpak zal voor een groot deel bepaald worden door wat je probeert te bereiken.
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.