mysql - How do I get multiple COUNT with multiple JOINS and multiple conditions? -
i have sql (mysql) i've can't figure out. application using uploaded photos there many tagged participants in photo , there possibility give photos vote between 1 5.
the original query gets votes photo , orders them amount of votes , average of votes.
now need limit returned photos ones more 1 participant. photos 1 participant should not accounted for.
simplified schema looks this.
photos ---------------------- | id | title | ---------------------- | 1 | fun stuff | | 2 | crazy girls | | 3 | single boy | photo_votes ------------------------------------------- | photo_id | grade | date | user_id | ------------------------------------------- | 1 | 3 | … | 12 | | 1 | 3 | … | 12 | | 2 | 5 | … | 14 | | 2 | 4 | … | 14 | | 3 | 4 | … | 15 | | 3 | 4 | … | 18 | photo_participants ------------------------- | photo_id | user_id | ------------------------- | 1 | 12 | | 1 | 21 | | 1 | 33 | | 2 | 14 | | 2 | 33 | | 3 | 12 |
this how far got:
select vote.photo_id, count(vote.photo_id) vote_count, avg(vote.grade) vote_average, count(pp.photo_id) participant_count photo_votes vote left join photos p on (vote.photo_id = p.id) left join photo_participants pp on (pp.photo_id = p.id) group vote.post_id, having vote_count >= 2 , vote_average >= 3 , participant_count > 1 order count desc, average desc;
basically i'm looking end with, excluding photo 1 participant:
votes ----------------------------------------------------------- | photo_id | vote_count | average | participant_count ----------------------------------------------------------- | 1 | 2 | 3 | 3 | 2 | 2 | 4.5 | 2
update
it turned out inefficient way of trying want. gordons answer below did solve problem, wanted join fields photos table well, "cartesian product"-issue became real problem - became heavy , slow query.
the solution ended adding cache-field photos table keeping track of how many participants in photo. in other words added 'participant_count' field 'photos' being updated every time change made participants table. run cron-job regularly make sure photos 'participant_count' up-to-date.
first, don't need left join
s this. shouldn't affect results. problem have cartesian product, because have 2 1-n relationships photos: votes , participants.
the proper way fix using subqueries:
select pv.photo_id, pv.vote_count, pv.vote_average, pp.participant_count (select pv.photo_id, count(*) vote_count, avg(grade) vote_average photo_votes pv group pv.photo_id ) pv join (select pp.photo_id, count(*) participant_count photo_participants p; group pv.photo_id ) pp on pv.photo_id = pp.photo_id pv.vote_count >= 2 , pv.vote_average >= 3 , pp.participant_count > 1 order pv.vote_count desc, pv.vote_average desc;
note don't need photos
table, because not using fields in it.
Comments
Post a Comment