Сумма нескольких соединенных таблиц через объединенную таблицу - PullRequest
0 голосов
/ 10 июля 2020

У меня есть запрос ниже, который получает subscriptions за projects за course, где первая дата проекта находится после указанной c даты. Однако я хотел бы получить общую сумму subscriptions для каждого курса.

SELECT
    `courses`.`name`,
    (
        (
            SELECT COUNT(*)
            FROM `participant_subscriptions`
            WHERE `participant_subscriptions`.`project_id` = `projects`.`id` AND `projects`.`course_id` = `courses`.`id`
        ) + (
            SELECT COUNT(*)
            FROM `participant_subscription_project`
            WHERE `participant_subscription_project`.`project_id` = `projects`.`id` AND `projects`.`course_id` = `courses`.`id`
        )
    ) AS `subscriptions`
FROM `courses`
JOIN `projects` ON `courses`.`id` = `projects`.`course_id`
WHERE (SELECT MIN(`date`) FROM `project_dates` WHERE `projects`.`id` = `project_dates`.`project_id`) >= '2020-01-01'

Это результат запроса выше:

| name     | subscriptions |
| Basics   | 6             |
| Basics   | 6             |
| Advanced | 2             |
| Advanced | 4             |
| Medium   | 2             |

То, что я хотел бы получить имеет следующий вид:

| name     | subscriptions |
| Basics   | 12            |
| Advanced | 6             |
| Medium   | 2             |

courses таблица:

  • id
  • имя

projects таблица:

  • id
  • имя
  • course_id

project_dates таблица

  • id
  • дата
  • идентификатор_проекта

participant_subscriptions таблица

  • идентификатор
  • идентификатор_участника
  • идентификатор_проекта

participant_subscription_project таблица

  • идентификатор
  • идентификатор_участника
  • идентификатор_проекта

Ответы [ 3 ]

2 голосов
/ 10 июля 2020

Хм ... Почему вы не можете использовать подзапрос с group by?

select name, sum(subscriptions) from
(SELECT `courses`.`name`,
       (
               (SELECT COUNT(*)
                FROM `participant_subscriptions`
                WHERE `participant_subscriptions`.`project_id` = `projects`.`id`
                  AND `projects`.`course_id` = `courses`.`id`) +
               (SELECT COUNT(*)
                FROM `participant_subscription_project`
                WHERE `participant_subscription_project`.`project_id` = `projects`.`id`
                  AND `projects`.`course_id` = `courses`.`id`)
           ) AS `subscriptions`
FROM `courses`
    JOIN `projects`
        ON `courses`.`id` = `projects`.`course_id`
WHERE (
          SELECT MIN(`date`)
          FROM `project_dates`
          WHERE `projects`.`id` = `project_dates`.`project_id`
      ) >= '2020-01-01')
GROUP BY 1
0 голосов
/ 13 июля 2020

Пришлось откорректировать ответ @KonstantinL. Вам также необходимо указать подзапрос alias. Я получил следующее:

SELECT `data`.`name`, SUM(`data`.`subscriptions`) AS `subscriptions`
        FROM (SELECT `c`.`name`,
                     (
                     (SELECT COUNT(*)
                              FROM `participant_subscriptions` `ps`
                              WHERE `ps`.`project_id` = `p`.`id`
            AND `p`.`course_id` = `c`.`id`) +
            (SELECT COUNT(*)
                              FROM `participant_subscription_project` `psp`
                              WHERE `psp`.`project_id` = `p`.`id`
            AND `p`.`course_id` = `c`.`id`)
                         ) AS `subscriptions`,
              FROM `courses` `c`
                       JOIN `projects` `p`
                            ON `c`.`id` = `p`.`course_id`
             WHERE (
                 SELECT MIN(`date`)
                 FROM `project_dates`
                 WHERE `projects`.`id` = `project_dates`.`project_id`
              ) >= '2020-01-01')
         )AS `data`
        GROUP BY 1
0 голосов
/ 10 июля 2020

Попробуйте следующее:

SELECT
    c.name,
    (
        ( SELECT COUNT(*) FROM participant_subscriptions ps WHERE ps.project_id = p.id AND p.course_id = c.id ) + 
        ( SELECT COUNT(*) FROM participant_subscription_project psp WHERE psp.project_id = p.id AND p.course_id = c.id)
    ) AS subscriptions
FROM courses c
JOIN projects p ON c.id = p.course_id
WHERE (SELECT MIN(date) FROM project_dates WHERE p.id = project_dates.project_id) >= '2020-01-01'
GROUP BY `courses`.`id` -- <--- edited

или

SELECT 
    c.name,
    COUNT(ps.id) participant_subscriptions_count,
    COUNT(psp.id) participant_subscription_project_count,
FROM projects p
    LEFT JOIN participant_subscriptions ps ON ps.project_id = p.id
    LEFT JOIN participant_subscription_project psp ON psp.project_id = p.id
    LEFT JOIN courses c ON c.id = p.course_id
-- WHERE (SELECT MIN(date) FROM project_dates WHERE p.id = project_dates.project_id) >= '2020-01-01' -- remove where consition for debugging
GROUP BY c.id

выше SQL - это другой подход. вы должны добавить participant_subscriptions_count и participant_subscription_project_count с любым языком программирования

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...