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 joins 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

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -