Использование CTE для подсчета количества строк во внутреннем запросе - PullRequest
0 голосов
/ 23 сентября 2018

Я изучаю CTE, и я столкнулся с упражнением, которое не могу решить.Это не домашнее задание , а упражнение из онлайн-курса, который я выбрал для изучения SQL.Меня интересует, где я допустил ошибку, и какое-то объяснение, поэтому ответы только с правильным кодом не помогут мне изучить CTE.

Задача состоит в том, чтобы подсчитать проекты, которые подняли от 100% до 150%минимальная сумма и те, которые подняли более 150%.

Я написал следующее CTE:

WITH nice_proj AS
  (SELECT project_id AS pid,
          amount AS amount,
          minimal_amount AS minimal
   FROM donation d
   INNER JOIN project p ON (d.project_id = p.id)
   GROUP BY pid,
            minimal,
            amount
   HAVING sum(amount) >= minimal_amount)
SELECT count(*) AS COUNT,
       (CASE
            WHEN sum(amount)/minimal <=1.5 THEN 'good projects'
            ELSE 'great projects'
        END) AS tag
FROM nice_proj
GROUP BY minimal;

Запрос ничего не возвращает, но он должен произвести что-то похожее на:

+-------+----------------+
| count | tag            |
+-------+----------------+
| 16    | good projects  |
+-------+----------------+
| 7     | great projects |
+-------+----------------+

Пожалуйста, посмотрите на таблицы (они урезаны):

Пожертвование

+----+------------+--------------+---------+------------+------------+
| id | project_id | supporter_id | amount  | amount_eur | donated    |
+----+------------+--------------+---------+------------+------------+
| 1  | 4          | 4            | 928.40  | 807.70     | 2016-09-07 |
+----+------------+--------------+---------+------------+------------+
| 2  | 8          | 18           | 384.38  | 334.41     | 2016-12-16 |
+----+------------+--------------+---------+------------+------------+
| 3  | 6          | 12           | 367.21  | 319.47     | 2016-01-21 |
+----+------------+--------------+---------+------------+------------+
| 4  | 2          | 19           | 108.62  | 94.50      | 2016-12-29 |
+----+------------+--------------+---------+------------+------------+
| 5  | 10         | 20           | 842.58  | 733.05     | 2016-11-30 |
+----+------------+--------------+---------+------------+------------+
| 6  | 4          | 15           | 653.76  | 568.77     | 2016-08-05 |
+----+------------+--------------+---------+------------+------------+
| 7  | 4          | 14           | 746.52  | 649.48     | 2016-08-03 |
+----+------------+--------------+---------+------------+------------+
| 8  | 10         | 3            | 962.36  | 837.25     | 2016-10-30 |
+----+------------+--------------+---------+------------+------------+
| 9  | 1          | 20           | 764.05  | 664.72     | 2016-08-24 |
+----+------------+--------------+---------+------------+------------+
| 10 | 10         | 4            | 1033.42 | 899.08     | 2016-02-26 |
+----+------------+--------------+---------+------------+------------+
| 11 | 5          | 6            | 571.90  | 497.55     | 2016-10-06 |
+----+------------+--------------+---------+------------+------------+

Проект

+----+------------+-----------+----------------+
| id | category   | author_id | minimal_amount |
+----+------------+-----------+----------------+
| 1  | music      | 1         | 1677           |
+----+------------+-----------+----------------+
| 2  | music      | 5         | 21573          |
+----+------------+-----------+----------------+
| 3  | travelling | 2         | 4952           |
+----+------------+-----------+----------------+
| 4  | travelling | 5         | 3135           |
+----+------------+-----------+----------------+
| 5  | travelling | 2         | 8555           |
+----+------------+-----------+----------------+
| 6  | video      | 4         | 6835           |
+----+------------+-----------+----------------+
| 7  | video      | 4         | 7978           |
+----+------------+-----------+----------------+
| 8  | games      | 1         | 4560           |
+----+------------+-----------+----------------+
| 9  | games      | 2         | 4259           |
+----+------------+-----------+----------------+
| 10 | games      | 1         | 5253           |
+----+------------+-----------+----------------+

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Мой совет - сначала объединить таблицу пожертвований, а затем сравнить ее с таблицей проекта.

При этом объединение пожертвований и проекта всегда составляет 1: 1.Это, в свою очередь, означает, что вам не нужно группировать по «значениям» (minimal_amount) , а только группировать по «идентификаторам» (project_id) .

WITH
  donation_summary AS
(
  SELECT
    project_id,
    SUM(amount)   AS total_amount
  FROM
    donation
  GROUP BY
    project_id
)
SELECT
  CASE WHEN d.total_amount <= p.minimal_amount * 1.5
       THEN 'good projects'
       ELSE 'great projects'
  END
     AS tag,
  COUNT(*)   AS project_count
FROM
  donation_summary   AS d
INNER JOIN
  project            AS p
    ON p.id = d.project_id
WHERE
  d.total_amount >= p.minimal_amount
GROUP BY
  tag

сказал, что я обычно использую следующий заключительный запрос и получаю два столбца, а не две строки ...

SELECT
  SUM(CASE WHEN d.total_amount <= p.minimal_amount * 1.5 THEN 1 ELSE 0 END)  AS good_projects,
  SUM(CASE WHEN d.total_amount >  p.minimal_amount * 1.5 THEN 1 ELSE 0 END)  AS great_projects
FROM
  donation_summary   AS d
INNER JOIN
  project            AS p
    ON p.id = d.project_id
WHERE
  d.total_amount >= p.minimal_amount
0 голосов
/ 23 сентября 2018

Вам необходимо удалить amount из группировки, это должно вернуть ожидаемый результат:

WITH nice_proj AS
  (SELECT project_id AS pid,
          sum(amount) AS amount,
          minimal_amount AS minimal
   FROM donation d
   INNER JOIN project p ON (d.project_id = p.id)
   GROUP BY pid,
            minimal
   HAVING sum(amount) >= minimal_amount)
SELECT count(*) AS COUNT,
       (CASE
            WHEN amount/minimal <=1.5 THEN 'good projects'
            ELSE 'great projects'
        END) AS tag
FROM nice_proj
GROUP BY tag;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...