tellen in een database
- achtbanen: achtbaanid, inversies
- ritten: achtbaanid, ritten
- eigenschappen: achtbaanid, eigenschapid
(bovenstaande zijn de gesimplificeerde weergaves omdat niet alle kolommen van belang zijn voor mijn vraag)
Ik wil graag tellen hoeveel keer iemand over de kop is gegaan. Dit doe ik middels de volgende query:
Code (php)
1
SELECT SUM(achtbanen.inversies*ritten.ritten) AS total_number_of_inversions FROM achtbanen INNER JOIN ritten ON achtbanen.achtbaanid=ritten.achtbaanid WHERE achtbanen.inversies!=0
Echter: er zijn achtbanen die je eerst vooruit doet en daarna achteruit. Hierbij heb je dus 2x het aantal inversies (over de kop moment in een achtbaan). Voorheen had ik dit simpel opgelost door het aantal inversies bij een achtbaan x2 te doen, echter wil ik dit anders aanpakken.
In de tabel met eigenschappen staat o.a. eigenschapid 17 wat betekent dat een achtbaan een zogeheten "boomerang" is, met andere woorden: de achtbaan gaat eerst vooruit en daarna achteruit. Op basis van die eigenschap zou het mogelijk moeten zijn te bepalen wanneer het aantal inversies verdubbeld moet worden, toch?
Tips hoe de query er dan uit komt te zien?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SELECT SUM(
ritten.ritten * achtbanen.inversies *
(CASE
WHEN EXISTS (
SELECT 1
FROM eigenschappen
WHERE eigenschappen.achtbaanid = achtbanen.achtbaanid
AND eigenschappen.eigenschapid = 17
)
THEN 2
ELSE 1
END)
) AS total_number_of_inversions
FROM achtbanen
INNER JOIN ritten ON achtbanen.achtbaanid = ritten.achtbaanid
WHERE achtbanen.inversies != 0
ritten.ritten * achtbanen.inversies *
(CASE
WHEN EXISTS (
SELECT 1
FROM eigenschappen
WHERE eigenschappen.achtbaanid = achtbanen.achtbaanid
AND eigenschappen.eigenschapid = 17
)
THEN 2
ELSE 1
END)
) AS total_number_of_inversions
FROM achtbanen
INNER JOIN ritten ON achtbanen.achtbaanid = ritten.achtbaanid
WHERE achtbanen.inversies != 0
Het is het proberen waard.
Thanks, dat lijkt inderdaad het gewenste resultaat te geven. Moet het nog even doortesten, maar dit is een goede basis.
Dus als het id 17 is dan geldt dat (eigenschapid = 17) gelijk is aan 1. Dat + 1 levert dan 2 op.
En als het niet voorkomt dan is die eigenschapid dus NULL. Dat is niet gelijk aan 17 en dus FALSE cq. 0.
0 + 1 levert 1 op voor de factor.
Dat maakt dat je niet in je formule opgescheept zit met 10 regels voor een CASE. En in dit geval vermijd ik ook nog een subquery, die in mijn ervaring vaak traag zijn.
Maar vooral dat laatste moet je wel even testen...
Code (php)
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
SELECT SUM(
ritten.ritten * achtbanen.inversies *
((eigenschappen.eigenschapid = 17) + 1)
) AS total_number_of_inversions
FROM achtbanen
INNER JOIN ritten ON achtbanen.achtbaanid = ritten.achtbaanid
LEFT JOIN eigenschappen ON eigenschappen.achtbaanid = achtbanen.achtbaanid AND eigenschappen.eigenschapid = 17
WHERE achtbanen.inversies != 0
ritten.ritten * achtbanen.inversies *
((eigenschappen.eigenschapid = 17) + 1)
) AS total_number_of_inversions
FROM achtbanen
INNER JOIN ritten ON achtbanen.achtbaanid = ritten.achtbaanid
LEFT JOIN eigenschappen ON eigenschappen.achtbaanid = achtbanen.achtbaanid AND eigenschappen.eigenschapid = 17
WHERE achtbanen.inversies != 0
Dank voor je input Ivo, maar jouw versie lijkt juist alleen de boomerang achtbanen terug te geven.