Meerdere queries ombouwen naar 1

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Ama saril

ama saril

14/06/2017 10:08:49
Quote Anchor link
Beste PhpHulpers,
Ik ben bezig met een klein scriptje om een overzicht mee te kunnen uitdraaien. Nu heb ik het overzicht al (omdat het snel moest worden geleverd) maar volgens mij is het niet 'efficient'. Vandaar de vraag of iemand een betere manier weet om dit op te lossen:

Ik heb op dit moment 3 tabellen:
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
user
----
id
name


diploma
----
id
number
date
user_id
type_id


diplomaType
----
id
name

?>


Wat ik wil is van elke user alle diploma's ophalen na 2015. Op dit moment heb ik dat opgelost door eerst alle gebruikers op te halen met een query en vervolgens per gebruiker alle diploma's op te halen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$users
= 'select id from user';   //het hele prepared gebeuren heb ik hier weggehaald om het kort te houden.
foreach($users as $u)
{

    $diplomas = select u.name, d.number, dt.name from user u
    JOIN diploma d on u.id = d.user_id
    JOIN diplomaType dt ON d.type_id = dt.id
    WHERE u.id = $u AND DATE(YEAR) > 2015; //deze dingen merge ik naar een array als resultaat
}

?>

Heb niet het hele script gepost anders wordt het zo lang. Nu zijn er 500 users wat betekent dat ik 500x de join query moet uitvoeren. Is het mogelijk om een overzicht uit de database te halen zonder te loopen door alle users en 500x een query uit te voeren? Want volgens mij is dit aardig 'inefficient'?

--edit code tags toegevoegd--
Gewijzigd op 14/06/2017 10:09:18 door Ama saril
 
PHP hulp

PHP hulp

07/12/2024 01:29:19
 
Ben van Velzen

Ben van Velzen

14/06/2017 10:41:09
Quote Anchor link
>> Wat ik wil is van elke user alle diploma's ophalen na 2015. Op dit moment heb ik dat opgelost door eerst alle gebruikers op te halen met een query en vervolgens per gebruiker alle diploma's op te halen.

En dat is niet nodig, want je selecteert nu per gebruiker opnieuw. Kijk maar eens naar de 2e query. Als je hier de user conditie uit weglaat ben je al klaar.
 
Thomas van den Heuvel

Thomas van den Heuvel

14/06/2017 10:53:27
Quote Anchor link
Ben van Velzen op 14/06/2017 10:41:09:
En dat is niet nodig, want je selecteert nu per gebruiker opnieuw. Kijk maar eens naar de 2e query. Als je hier de user conditie uit weglaat ben je al klaar.

Niet helemaal ingeval een gebruiker meerdere diploma's kan hebben? In dat geval zou je een LEFT JOIN van users op diploma's moeten doen.

EDIT: of de resulterende query efficiënt is hangt ook af van het type database(-engine) en of (en hoe) de relaties zijn gedefinieerd. Indien je de MyISAM engine gebruikt doe je er verstandig aan om indexen aan te maken op user_id en type_id. Nadeel van deze engine is dat tabellen nog steeds enigszins als los zand aan elkaar hangen. Indien je de InnoDB engine gebruikt zouden user_id en type_id al foreign key constraints moeten zijn naar hun bijbehorende tabellen. Voordeel van deze methode is dat dit soort relaties (op databaseniveau) de integriteit van de data in deze tabellen (beter) waarborgen.
Gewijzigd op 14/06/2017 11:01:47 door Thomas van den Heuvel
 
Ben van Velzen

Ben van Velzen

14/06/2017 11:00:41
Quote Anchor link
Uhm.. Waarom? Een LEFT JOIN is alleen van toepassing wanneer je verwacht dat er gevallen zijn waar je 0 resultaten kan krijgen en je alsnog de user zou willen zien.
 
Thomas van den Heuvel

Thomas van den Heuvel

14/06/2017 11:04:52
Quote Anchor link
Een JOIN is een INNER JOIN bij mijn weten. Dit houdt in dat zelfs als een user meer dan één diploma heeft er altijd maar één diploma uitrolt in de resultaten?

Los hiervan, om dit soort beslissingen te nemen ((INNER) JOIN vs LEFT JOIN etc.) zul je meer moeten weten over het gedrag van de data in kwestie.

Zie ook mijn toevoeging over efficiëntie in mijn vorige reactie.
 
Ben van Velzen

Ben van Velzen

14/06/2017 11:11:38
Quote Anchor link
>> Een JOIN is een INNER JOIN bij mijn weten. Dit houdt in dat zelfs als een user meer dan één diploma heeft er altijd maar één diploma uitrolt in de resultaten?

Niet echt. Het houdt in dat de user gedupliceerd wordt per diploma. Een LEFT JOIN is 0 of meer, INNER is 1 of meer.
 
Ama saril

ama saril

14/06/2017 11:15:57
Quote Anchor link
Bedankt voor de snelle reacties. Ik zal alle suggesties even uittesten zodra ik weer thuis ben vanavond. Ik zal de resultaten hier posten.
 
Ivo P

Ivo P

14/06/2017 11:55:49
Quote Anchor link
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
SELECT u.name, d.number, dt.name
FROM user u
JOIN diploma d on u.id = d.user_id
JOIN diplomaType dt ON d.type_id = dt.id
WHERE  AND YEAR(d.date) > 2015
ORDER BY u.name


Je filter op jaartal klopte niet.
En ik zou ze sorteren op naam: dan krijg je alle records per naam achterelkaar.
Als iemand dan 2 of meer diploma's heeft, komen die achter elkaar aan bod. Dan kun je eventueel zorgen dat bij het weergeven je de naam niet steeds herhaalt.
 



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.