Edwardvb schreef op maandag 22 oktober 2007 @ 20:40:
[...]
ach je hebt gelijk ook... kzit niet goed na te denken... volgens mij moet de max wel in de where genoemd kunnen worden... heb dat vaak genoeg gedaan, maar de preciese syntax weet ik zo even niet zeker uit de kop...
maar lijkt me dat TS dat ook prima zelf kan proberen....
Nouja, als je m'n reactie goed leest zie je hoe je dit eigenlijk eenvoudig op kan lossen: namelijk door straffeloos te groeperen ook op reactions.post_date. Ik moet er alleen even bij zeggen dat het formeel gezien handig is om in het geval van een group by expliciet aan te geven waar je op selecteert (ook zodat je kan zien wat wel en niet mag in de group by clausule): volgens mij was MySQL 'een van die db's' die dit toelaat om weg te laten, en impliciet zelf z'n conclusies hierover trekt.
Als dat niet is wat TS wil, zou ik TS even aanraden om naar sql derivatie middels setnotatie te kijken. Dit is een formele methode om SQL queries wiskundig te 'berekenen' middels setcomprehensie. Als ik vanavond nog even tijd heb na 't doen van m'n eigen huiswerk zal ik er wel even naar kijken.
P.S. Ik zou zelf nog even een foreign key constraint overwegen op reactions.itemid (references foto.id). Daar moeten beide tabellen fotos en reactions echter wel innodb voor zijn iirc.
edit:
Even in een paar minuten in elkaar gedraaid. Ook al is correctheid even verkozen boven efficientie, weet ik niet zeker of het klopt. Is alweer een tijdje geleden voor me, en het kan w.s. korter (ik vermoed dat er tautologie is bij de "er is een reactie op een foto", i.e. dat dit gedeelte evt weggelaten kan worden.
De setnotatie icm predicaten.
code:
1
2
3
4
5
6
7
8
9
10
| { "Laatste reactie van elke foto" }
{ r | "r is een reactie op een foto" & "r is de laatste reactie van elke foto" @ r }
{ r | (EXISTS f @ r.itemid = f.id) & "r is de laatste reactie van elke foto" @ r}
{ r | (EXISTS f @ r.itemid = f.id) & "voor elke f2 is r de meest recente reactie ervan" @ r}
{ r | (EXISTS f @ r.itemid = f.id) & (FORALL f2 | "r op f2" @ "r is de meest recente") @ r}
{ r | (EXISTS f @ r.itemid = f.id) & (FORALL f2 | r.itemid = f2.id @ "er bestaat geen r2 op f2 waarvoor geldt r2.post_date > r.post_date") @ r}
{ r | (EXISTS f @ r.itemid = f.id) & (FORALL f2 | r.itemid = f2.id @ (NOT EXISTS r2 | r2.itemid = f2.id @ r2.post_date > r.post_date)) @ r}
{ r | (EXISTS f @ r.itemid = f.id) & (NOT EXISTS f2 | r.itemid = f2.id @ NOT((NOT EXISTS r2 | r2.itemid = f2.id @ r2.post_date > r.post_date))) @ r}
{ r | (EXISTS f @ r.itemid = f.id) & (NOT EXISTS f2 | r.itemid = f2.id @ (EXISTS r2 | r2.itemid = f2.id @ r2.post_date > r.post_date))) @ r}
{ r, f | r.itemid = f.id & (NOT EXISTS f2 | r.itemid = f2.id @ (EXISTS r2 | r2.itemid = f2.id @ r2.post_date > r.post_date))) @ r} |
Hieruit volgt:
SQL:
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
| SELECT
r.* -- hier moet je dus even bepalen wat je precies van r wil.
FROM
reactions r, fotos f
WHERE
r.itemid = f.id
AND
NOT EXISTS(
SELECT
*
FROM
fotos f2
WHERE
r.itemid = f2.id
AND
EXISTS(
SELECT
*
FROM
reactions r2
WHERE
r2.itemid = f2.id
AND
r2.post_date > r.post_date
)
)
ORDER BY r.post_date DESC
LIMIT 15 |
[
Voor 45% gewijzigd door
prototype op 23-10-2007 00:17
]