Обобщая мой запрос для выполнения всех данных вместо указания c id - PullRequest
0 голосов
/ 27 февраля 2020

У меня есть конкретный c запрос, который работает, когда я жестко кодирую идентификатор, для которого он должен работать. Я хотел бы запустить его для всех идентификаторов в моей базе данных.

Это типичная настройка:

CREATE TABLE `dummy` (
    `total` INT(11) NULL DEFAULT NULL,
    `a_id` INT(11) NULL DEFAULT NULL,
    `month` INT(11) NULL DEFAULT NULL
);

Data:

total | a_id | month
2     | 1    | 3
4     | 1    | 5
3     | 1    | 6
6     | 1    | 9
3     | 2    | 4
6     | 2    | 10


CREATE TABLE `months` (
    `month` INT(11) NULL DEFAULT NULL
);

Data: Just the values 1 through 12

Чего я хочу добиться, это использовать month в качестве метки времени, и для каждого a_id получите их общее количество за этот месяц, с ноль для месяцев, которые не установлены (но только между первым месяцем и последним месяцем, из что a_id).

Мой запрос пока:

SELECT c.month, COALESCE(d.total, 0) AS 'total', COALESCE(d.a_id, 1) AS 'a_id'
FROM (
    SELECT month
    FROM months
    WHERE month >= (SELECT MIN(month) FROM dummy WHERE a_id = 1)
    AND month <= (SELECT MAX(month) FROM dummy WHERE a_id = 1)
) c
LEFT outer JOIN (
    SELECT *
    FROM dummy
    WHERE a_id = 1
) d ON d.month = c.month
ORDER BY c.month;

И его вывод:

month | total | a_id
3     | 2     | 1
4     | 0     | 1
5     | 4     | 1
6     | 3     | 1
7     | 0     | 1
8     | 0     | 1
9     | 6     | 1

Как я могу изменить этот запрос и получить вывод для каждые a_id в таблице, без внешней программы, такой как PHP каждый раз менять идентификатор?

1 Ответ

2 голосов
/ 27 февраля 2020

Кажется, вам нужно

SELECT months.month, 
       COALESCE(dummy.total, 0) total, 
       a_ids.a_id
FROM months
CROSS JOIN ( SELECT DISTINCT a_id
             FROM dummy ) a_ids
LEFT JOIN dummy ON months.month = dummy.month
               AND a_ids.a_id = dummy.a_id
INNER JOIN ( SELECT MIN(month) min_month,
                    MAX(month) max_month
             FROM dummy ) borders ON months.month BETWEEN borders.min_month 
                                                      AND borders.max_month
ORDER BY a_ids.a_id, months.month;

или

SELECT months.month, 
       COALESCE(dummy.total, 0) total, 
       a_ids.a_id
FROM months
CROSS JOIN ( SELECT DISTINCT a_id
             FROM dummy ) a_ids
LEFT JOIN dummy ON months.month = dummy.month
               AND a_ids.a_id = dummy.a_id
INNER JOIN ( SELECT MIN(month) min_month,
                    MAX(month) max_month,
                    a_id
             FROM dummy
             GROUP BY a_id ) borders ON months.month BETWEEN borders.min_month 
                                                         AND borders.max_month
                                    AND a_ids.a_id = borders.a_id
ORDER BY a_ids.a_id, months.month;

скрипка

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