Рассчитать общее количество событий на город на основе множества условий HABTM в CakePHP / MySQL - PullRequest
0 голосов
/ 13 июля 2011

На моей странице «Списки событий» я перечисляю все события, которые происходят СЕЙЧАС или позже.

Затем пользователь может выбрать, в каком городе (ах), типе (ах) события, подтипе (ах) события и т. Д. Он хочет запросить, чтобы вернуть только те события, которые соответствуют его выбранному элементу (ам).

У меня это работает просто отлично - я строю свои соединения / условия ... и т. Д. На основе их входных данных, и он возвращает правильные события с пагинацией ... и т. Д.

Проблема теперь в том, что у меня есть список городов в левой части страницы, и я хочу иметь количество событий в этих городах (то же самое с типом, подтипом .. и т. Д.), То есть:

New York (16)
Chicago (15)
Austin (8)
...

Sports (6)
  - Baseball (2)
  - Basketball (2)
  - Football (0)
Outdoors (5)
...

Это не будет большой проблемой, за исключением того, что я использую объединения для получения необходимых мне данных, поэтому, когда я пытаюсь это сделать:

SELECT COUNT(`VenueCity`.`id`) + COUNT(RestaurantCity.id) AS total,
`VenueCity`.`name`, `VenueCity`.`id`, `VenueCity`.`slug`, `RestaurantCity`.`name`,
`RestaurantCity`.`id`, `RestaurantCity`.`slug` FROM `events` AS `Event`
INNER JOIN schedules AS `Schedule` ON (`Schedule`.`event_id` = `Event`.`id`)
INNER JOIN dates AS `Date` ON (`Date`.`schedule_id` = `Schedule`.`id`)
LEFT JOIN restaurants AS `Restaurant` ON (`Restaurant`.`id` = `Event`.`restaurant_id`) LEFT JOIN venues AS `Venue` ON (`Venue`.`id` = `Event`.`venue_id`)
LEFT JOIN cities AS `VenueCity` ON (`Venue`.`city_id` = `VenueCity`.`id`)
LEFT JOIN cities AS `RestaurantCity` ON (`Restaurant`.`city_id` = `RestaurantCity`.`id`)
WHERE `Event`.`name` IS NOT NULL
AND `Event`.`approval_status_id` = 1
AND `Date`.`start` >= '2011-07-12 16:45:39'
GROUP BY `VenueCity`.`id`
ORDER BY `total` DESC 

Возвращает счет для КАЖДОЙ существующей даты (т. Е. Если имеется 10 событий, каждое из которых имеет 5 дат, в качестве количества будет показано 50).

Не говоря уже о том, что мне снова нужно выполнить этот сложный запрос, после того, как он уже был выполнен дважды для нумерации страниц Cake. И я предполагаю, что если я продолжу идти по этому пути, мне придется делать это снова для каждого типа, подтипа и подтипа.

TLDR:

У меня сложный многопользовательский запрос, который получает события на основе Event-Schedule-> Date. Мне также нужно иметь возможность сообщить (в том же запросе или новом (-ых) запросе), сколько событий происходит для каждого города, типа, подтипа ... и т. Д. И т. Д.

Я скрещиваю пальцы, ответ: "О, это просто, вы можете просто сделать __ " - но приму любой совет / помощь, которая у вас есть.

Ответы [ 2 ]

0 голосов
/ 13 июля 2011

Оказывается, мне просто нужно немного подправить.Вместо:

COUNT(`VenueCity`.`id`) + COUNT(RestaurantCity.id) AS total

Я использовал это:

COUNT(DISTINCT Event.id) AS total

Таким образом, он по-прежнему группируется по городу, но счет основан на событии, а не на городе.Должно было быть легко поймать, но - live'n'learn!:)

Полный запрос:

SELECT COUNT(DISTINCT Event.id) AS total, `VenueCity`.`name`, `VenueCity`.`id`, 
`VenueCity`.`slug`, `RestaurantCity`.`name`, `RestaurantCity`.`id`, 
`RestaurantCity`.`slug` FROM `events` AS `Event` 
INNER JOIN schedules AS `Schedule` ON (`Schedule`.`event_id` = `Event`.`id`) 
INNER JOIN dates AS `Date` ON (`Date`.`schedule_id` = `Schedule`.`id`) 
LEFT JOIN restaurants AS `Restaurant` ON (`Restaurant`.`id` = `Event`.`restaurant_id`)  
LEFT JOIN venues AS `Venue` ON (`Venue`.`id` = `Event`.`venue_id`) 
LEFT JOIN cities AS `VenueCity` ON (`Venue`.`city_id` = `VenueCity`.`id`) 
LEFT JOIN cities AS `RestaurantCity` ON (`Restaurant`.`city_id` = `RestaurantCity`.`id`)  
WHERE `Event`.`name` IS NOT NULL AND `Event`.`approval_status_id` = 1 
AND `Date`.`start` >= '2011-07-12 17:59:24' 
GROUP BY `VenueCity`.`id` ORDER BY `total` DESC 
0 голосов
/ 13 июля 2011

Попробуйте выполнить подзапрос в таблице расписаний, что-то вроде этого даст вам одну случайную дату (скорее всего, первую дату, которая была введена в таблицу) для каждого события.Может потребоваться немного отладки, но это должно помочь вам ...


SELECT COUNT(`VenueCity`.`id`) + COUNT(RestaurantCity.id) AS total,
`VenueCity`.`name`, `VenueCity`.`id`, `VenueCity`.`slug`, `RestaurantCity`.`name`,
`RestaurantCity`.`id`, `RestaurantCity`.`slug` FROM `events` AS `Event`
INNER JOIN 

(SELECT MIN(subSchedule.`id`) AS `id`,subSchedule.`event_id` 
   FROM `schedules` AS subSchedule
   INNER JOIN dates AS subDate ON (subDate.`schedule_id` = subSchedule.`id`)   
   WHERE `subDate`.`start` >= '2011-07-12 16:45:39'
   GROUP BY subSchedule.`event_id`
) AS Schedule

    ON (`Schedule`.`event_id` = `Event`.`id`)

INNER JOIN dates AS `Date` ON (`Date`.`schedule_id` = `Schedule`.`id`)
LEFT JOIN restaurants AS `Restaurant` ON (`Restaurant`.`id` = `Event`.`restaurant_id`) LEFT JOIN venues AS `Venue` ON (`Venue`.`id` = `Event`.`venue_id`)
LEFT JOIN cities AS `VenueCity` ON (`Venue`.`city_id` = `VenueCity`.`id`)
LEFT JOIN cities AS `RestaurantCity` ON (`Restaurant`.`city_id` = `RestaurantCity`.`id`)
WHERE `Event`.`name` IS NOT NULL
AND `Event`.`approval_status_id` = 1
AND `Date`.`start` >= '2011-07-12 16:45:39'
GROUP BY `VenueCity`.`id`
ORDER BY `total` DESC 

@ Дэйв, я не могу комментировать, я полагаю, это потому, что я новичок в StackOverflow.Но в основном то, что вы пытаетесь сделать с подзапросом, - это создать псевдотаблица, в которой по одной строке для каждого события.Результаты этого подзапроса будут использоваться в внешнем запросе, как и в реальной таблице.Я считаю, что вы можете получить то, что вы хотите, сгруппировав по event_id, а затем с помощью функции итога, чтобы получить другие поля, которые вы хотите.MIN () даст вам наименьший schedule.id, а с INNER JOIN к дате и предложению where будет наименьшим идентификатором, который соответствует предложению where.Вы можете протестировать подзапрос отдельно, чтобы точно настроить его.

...