Mysql Twee Counts geven dezelfde resultaat
en in 'beheer_notities bn' maar 1
Toch geeft hij bij beide counts 2, waarom?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
SELECT
SQL_CALC_FOUND_ROWS bv.bv_id,
bv.ba_id,
COUNT(bn.bn_notitie) as bn_aantal,
COUNT(bsol.bsol_motivatie) as bsol_aantal
FROM beheer_vacatures bv
LEFT JOIN beheer_solicitaties bsol
ON bv.bv_id = bsol.bv_id
LEFT JOIN beheer_notities bn
ON bv.bv_id = bn.bv_id
GROUP BY
bv.bv_id
SQL_CALC_FOUND_ROWS bv.bv_id,
bv.ba_id,
COUNT(bn.bn_notitie) as bn_aantal,
COUNT(bsol.bsol_motivatie) as bsol_aantal
FROM beheer_vacatures bv
LEFT JOIN beheer_solicitaties bsol
ON bv.bv_id = bsol.bv_id
LEFT JOIN beheer_notities bn
ON bv.bv_id = bn.bv_id
GROUP BY
bv.bv_id
Dit kan je alleen maar verhelpen door het tellen in een subquery te doen, i.e:
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
..........
LEFT JOIN
(SELECT bv_id, COUNT(*) bssol_aantal
FROM beheer_solicitaties
GROUP BY bv_id) bsol
ON bv.bv_id = bsol.bv_id
LEFT JOIN
/* de volgende subquery */
LEFT JOIN
(SELECT bv_id, COUNT(*) bssol_aantal
FROM beheer_solicitaties
GROUP BY bv_id) bsol
ON bv.bv_id = bsol.bv_id
LEFT JOIN
/* de volgende subquery */
En let op dat als je met SQL_CALC_FOUND_ROWS werkt, dit vaker (aanzienlijk) langzamer is dan twee queries (één voor het result met de limit en één met SELECT count(*) voor het totaal aantal)
Ik gebruik SQL_CALC_FOUND_ROWS om vooraf te bepalen hoeveel results er altijd totaal zijn.
Dan fetch ik dat:
Code (php)
1
2
3
4
5
2
3
4
5
$total = $this->db->query("SELECT FOUND_ROWS()");
$rowTotal = $total->fetch();
$total_results = $rowTotal['FOUND_ROWS()'];
$arrayed = $query->fetchAll();
$arrayed['total_results'] = $total_results;
$rowTotal = $total->fetch();
$total_results = $rowTotal['FOUND_ROWS()'];
$arrayed = $query->fetchAll();
$arrayed['total_results'] = $total_results;
Dan met php en als iemand 10 of 100 tegelijk wil op de pagina dan doe ik dat met $per_page
Code (php)
1
2
2
$total_results = $vacatures['total_results'];
$total_pages = ceil($total_results / $per_page);
$total_pages = ceil($total_results / $per_page);
In hoeverre is dit langzamer moet ik dit stukje onder dan vervangen:
Naar SELECT COUNT(bv.bv_id) as total_results, volgende_columns..
waarom is er dan uberhaupt SQL_CALC_FOUND_ROWS?
Gewijzigd op 17/02/2014 16:18:56 door Francoi gckx
Het levert in ieder geval maar zelden voordeel, omdat sql_calc_found_rows altijd een full tablescan tot gevolg heeft. Dit is niet het geval als je met SELECT count(*) FROM .... WHERE .... als de kolom(men) in de WHERE een index heeft (hebben).
In jouw geval werk je ook nog eens met group_by en left join dus kan je veel beter het aantal vacuteres bepalen:
En het dan uit de andere query SQL_CALC_FOUND_ROWS gewoon weglaten
Moet ik voor de volgende situatie ook een sub query gebruiken?
Ik wil maar 1 vacature gegevens laten zien met daar onder al zijn solicitaties
Zonder subquery en alleen met left join en alle select data in het begin;
Krijg ik met een vacature die 2 solicitaties heeft ook 2 keer dezelfde vacature gegevens. Nu zou dit wel met PHP oplosbaar te zijn. Maar toch als we toch over efficientie hebben.
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
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
SELECT
bsol.bsol_naam,
bsol.bsol_email,
bsol.bsol_motivatie,
bsol.bsol_cvlink,
bsol.bsol_datum,
bsol.bsol_id,
ba_woonplaats,
bb.bb_bedrijfsnaam
FROM beheer_solicitaties bsol
LEFT JOIN beheer_bedrijven bb
ON bb.ba_id = bsol.ba_id
LEFT JOIN (SELECT DISTINCT bv_id, bv_beschrijving,
bv_functie,
bv_plaats,
bv_categorie, bv_beschikbaar,
bv_ervaring,
bv_datum,
ba_id,
bv_datum_gewijzigd
FROM beheer_vacatures
GROUP BY bv_id) bv
ON bsol.bv_id = bv.bv_id
LEFT JOIN beheer_accounts ba
ON bsol.ba_id = ba.ba_id
WHERE bv.bv_id = 7
ORDER BY bsol.bsol_id
bsol.bsol_naam,
bsol.bsol_email,
bsol.bsol_motivatie,
bsol.bsol_cvlink,
bsol.bsol_datum,
bsol.bsol_id,
ba_woonplaats,
bb.bb_bedrijfsnaam
FROM beheer_solicitaties bsol
LEFT JOIN beheer_bedrijven bb
ON bb.ba_id = bsol.ba_id
LEFT JOIN (SELECT DISTINCT bv_id, bv_beschrijving,
bv_functie,
bv_plaats,
bv_categorie, bv_beschikbaar,
bv_ervaring,
bv_datum,
ba_id,
bv_datum_gewijzigd
FROM beheer_vacatures
GROUP BY bv_id) bv
ON bsol.bv_id = bv.bv_id
LEFT JOIN beheer_accounts ba
ON bsol.ba_id = ba.ba_id
WHERE bv.bv_id = 7
ORDER BY bsol.bsol_id
Het geeft geen foutmelding maar het lijkt er op dat hij alles in de subquery select negeert:/
Let op de volgorde waarin je de selecteert, je begint met "ik wil 1 vacature" maar in de from heb je de sollicitaties tabel en daarachter een left join
Probeer een query op dezelfde manier op te bouwen zoals je de vraag stelt, dus geef mij de sollicaties die bij een vacature horen resulteert in
In jouw voorbeeld selecteer je eesrt alle sollicitaties en daarna ga je kijken of er eventueel een vacature bij hoort.
Ik heb het nu omgedraaid een subquery er ingebouwd maar klopt het dat een
lijst van geselecteerde items in een sub query iets extraas nodig heeft om opgenomen te worden
in een tabel dan? Hij doet namelijk niks met de lijst van geselecteerde items in de subquery.
Hij geeft als het ware alleen de vacature weer met zn gegevens
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
SELECT
bv.bv_beschrijving,
bv.bv_functie,
bv.bv_plaats,
bv.bv_categorie, bv.bv_beschikbaar,
bv.bv_ervaring,
bv.bv_datum,
bv.ba_id,
bv_datum_gewijzigd,
ba_woonplaats,
bb.bb_bedrijfsnaam
FROM beheer_vacatures bv
LEFT JOIN (SELECT bv_id, bsol_naam,
bsol_email,
bsol_motivatie,
bsol_cvlink,
bsol_datum,
bsol_id,
ba_id
FROM beheer_solicitaties
GROUP BY bv_id) as bsol
ON bv.bv_id = bsol.bv_id
WHERE bv.bv_id = 7
bv.bv_beschrijving,
bv.bv_functie,
bv.bv_plaats,
bv.bv_categorie, bv.bv_beschikbaar,
bv.bv_ervaring,
bv.bv_datum,
bv.ba_id,
bv_datum_gewijzigd,
ba_woonplaats,
bb.bb_bedrijfsnaam
FROM beheer_vacatures bv
LEFT JOIN (SELECT bv_id, bsol_naam,
bsol_email,
bsol_motivatie,
bsol_cvlink,
bsol_datum,
bsol_id,
ba_id
FROM beheer_solicitaties
GROUP BY bv_id) as bsol
ON bv.bv_id = bsol.bv_id
WHERE bv.bv_id = 7
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
(SELECT bv_id, bsol_naam,
bsol_email,
bsol_motivatie,
bsol_cvlink,
bsol_datum,
bsol_id,
ba_id
FROM beheer_solicitaties
GROUP BY bv_id)
bsol_email,
bsol_motivatie,
bsol_cvlink,
bsol_datum,
bsol_id,
ba_id
FROM beheer_solicitaties
GROUP BY bv_id)
Een vage group by, daar hebben we het pas nog over gehad ;-)
Gewijzigd op 17/02/2014 21:53:40 door Ger van Steenderen
Zonder group by krijg ik 1 vacature maar dan ook alleen de vacature gegevens.
Met krijg ik maar liefst twee vacatures, dezelfde, maar dan ook alleen de vacature gegevens.
Ik denk dat ik DISTINCT nodig heb op de beheer_vacatures en dan hoe worden de subquery items opgenomen?
Dus eerst de algemene info ophalen, en dan de bij behorende sollicitaties, ik denk dat je het jezelf daar een stuk makkelijker mee maakt.
Toch uit nieuwsgierigheid had het wel gekund?
Of wordt de query dan groter dan de twee afzonderlijke queries naast elkaar en met meer toeters en bellen :)?
Met één query wordt de algemene data een x aantal maal herhaald, terwijl je hem maar één maal nodig hebt.
Daar tegen over een extra query.
Maakt het veel verschil in performance? Niet noemenswaardig.