Reputation: 641
Given the following tables
+-----------+-------------+----------+
| tours | tour_user | tag_tour |
+-----------+-------------+----------+
| id | tour_id | tag_id |
| startdate | user_id | tour_id |
+-----------+-------------+----------+
I want to achieve a result set like this:
+-----------------+----------------+----------------+
| DATE(startdate) | COUNT(user_id) | COUNT(tour_id) |
+-----------------+----------------+----------------+
| 2017-12-01 | 55 | 32 |
+-----------------+----------------+----------------+
Described in words the amount of users paticipated on a tour and the amount of tours should be aggregated by days.
Additionaly the count of tour and user participation should be filterable via tags which are attachted to tours via tag_tour table (many-to-may-relation). E.g. I want only the tour and user count of tours which have tag_id 1 AND 2 attaches.
Currently I go with this Query:
SELECT DATE(tours.start) AS acum_date,
COUNT(tour_user.user_id) AS guide_assignments,
A.tour_count
FROM `tour_user`
LEFT JOIN `tours` ON `tours`.`id` = `tour_user`.`tour_id`
LEFT JOIN
(SELECT DATE(tours.start) AS tour_date,
COUNT(DISTINCT tours.id) AS tour_count
FROM tours
GROUP BY DATE(tours.start)) AS A ON `A`.`tour_date` = DATE(tours.start)
GROUP BY `acum_date`
ORDER BY `acum_date` ASC
The problem with this is, that only the total tour/user count is returned and not the filtered one.
Upvotes: 1
Views: 28
Reputation: 1270391
The base query is:
select t.startdate, count(tu.user_id) as num_users, count(distinct t.id) as num_tours
from tours t left join
tour_user tu
on tu.tour_id = t.id
group by t.startdate;
In this case, I would recommend using exists
for filtering the tags:
select t.startdate, count(tu.user_id) as num_users, count(distinct t.id) as num_tours
from tours t left join
tour_user tu
on tu.tour_id = t.id
where exists (select 1 from tour_tags tt where tt.tour_id = t.tid and tt.tag_id = <tag1>) and
exists (select 1 from tour_tags tt where tt.tour_id = t.tid and tt.tag_id = <tag2>)
group by t.startdate;
Upvotes: 1