MySQL ROLL UP запрос - PullRequest
       7

MySQL ROLL UP запрос

0 голосов
/ 10 октября 2019

У меня есть этот запрос MySQL, который имеет проблему с последней строкой. Я хочу только последний столбец (всего) и остальные строки, я хочу их NULL.

QUERY:

SELECT q.id_socio, q.nome, q.nif, q.num_mecanografico, SUM(IFNULL(qt.quota_nova, quota)) AS 'quota'
FROM 
    (SELECT id_socio, quota_nova FROM QUOTAS_TEMPORARIAS WHERE ANO = 2019 AND MES = 10) 
    AS qt 
RIGHT JOIN 
    (SELECT id_socio, nome, nif, num_mecanografico, quota FROM SOCIO s, TIPO_PAGAMENTO tp, AGRUPAMENTO a, ORGANIZACAO o WHERE s.ID_TIPO_PAGAMENTO = tp.ID_TIPO_PAGAMENTO AND s.id_agrupamento = a.id_agrupamento AND a.id_organizacao = o.id_organizacao AND o.id_organizacao = 1 AND s.id_tipo_pagamento = 1) 
    AS q
ON q.id_socio = qt.id_socio 
GROUP BY q.id_socio WITH ROLLUP 
HAVING q.nome IS NOT NULL AND q.nif IS NOT NULL AND q.num_mecanografico IS NOT NULL OR q.id_socio IS NULL 

Результат:

enter image description here

Ожидаемые результаты:

enter image description here

Ответы [ 3 ]

0 голосов
/ 10 октября 2019

Я бы посоветовал вам сделать что-то подобное.

WITH main_query AS (
    SELECT
        id_socio,
        nome,
        nif,
        num_mecanografico,
        IFNULL(
            (SELECT
                quota_nova
            FROM QUOTAS_TEMPORARIAS temp_quota
            WHERE id_socio = temp_quota.id_socio
                AND ANO = 2019
                AND MES = 10),
            quota) quota
    FROM SOCIO socio,
        TIPO_PAGAMENTO tipo_pag,
        AGRUPAMENTO agrup,
        ORGANIZACAO org
    WHERE socio.ID_TIPO_PAGAMENTO = tipo_pag.ID_TIPO_PAGAMENTO
        AND socio.id_agrupamento = agrup.id_agrupamento
        AND agrup.id_organizacao = o.id_organizacao
        AND org.id_organizacao = 1
        AND socio.id_tipo_pagamento = 1
)
    SELECT * FROM main_query
UNION
    SELECT NULL, NULL, NULL, NULL, SUM(quota) FROM main_query

GROUP BY id_socio WITH ROLLUP
HAVING nome IS NOT NULL
    AND nif IS NOT NULL
    AND num_mecanografico IS NOT NULL
    OR id_socio IS NULL

Вам нужно будет создать объединение, чтобы включить итоговую строку в ваши результаты, не имея других значений. На самом деле, я не рекомендую делать это для результата запроса приложения, потому что для восстановления итоговых результатов потребуется специальная обработка, я бы предложил вам использовать два отдельных запроса. Но теперь это зависит от вас:)

0 голосов
/ 10 октября 2019

Мне трудно быть уверенным, не видя таблицы и ссылки на данные, но если те изображения, которые вы разместили, верны, то это должно сработать: сохраните набор данных в две временные таблицы, затем объедините таблицы, чтобы получить нужные данные:

CREATE TEMPORARY TABLE t1
SELECT q.id_socio, q.nome, q.nif, q.num_mecanografico, SUM(IFNULL(qt.quota_nova, 
quota)) AS 'quota' 
FROM 
(SELECT id_socio, quota_nova FROM QUOTAS_TEMPORARIAS WHERE ANO = 2019 AND MES = 10) 
AS qt 
RIGHT JOIN 
(SELECT id_socio, nome, nif, num_mecanografico, quota 
  FROM SOCIO s, TIPO_PAGAMENTO tp, AGRUPAMENTO a, ORGANIZACAO o 
  WHERE s.ID_TIPO_PAGAMENTO = tp.ID_TIPO_PAGAMENTO AND s.id_agrupamento = 
  a.id_agrupamento AND a.id_organizacao = o.id_organizacao AND o.id_organizacao = 1 
  AND 
  s.id_tipo_pagamento = 1
 ) AS q ON q.id_socio = qt.id_socio 
GROUP BY q.id_socio 
WITH ROLLUP 
HAVING q.nome IS NOT NULL AND q.nif IS NOT NULL AND q.num_mecanografico IS NOT NULL 
OR q.id_socio IS NULL;

CREATE TEMPORARY TABLE t2
SELECT null,null,null,null,quota FROM t1 WHERE id_socio IS NOT NULL;

SELECT * FROM t1
UNION ALL
SELECT * FROM t2;
0 голосов
/ 10 октября 2019

Расширение MySQL разрешает именовать столбец, который отсутствует в списке GROUP BY, в списке выбора. (Информацию о неагрегированных столбцах и GROUP BY см. В разделе 12.20.3, «Обработка MySQL для GROUP BY» .) В этом случае сервер может свободно выбирать любое значение из этого неагрегированного столбцастрок, и это включает в себя дополнительные строки, добавленные WITH ROLLUP.

Это поведение разрешено, когда режим ONLY_FULL_GROUP_BY SQL не включен. Если этот режим включен, сервер отклоняет запрос как недопустимый, поскольку столбец не указан в предложении GROUP BY. С включенным ONLY_FULL_GROUP_BY вы все равно можете выполнить запрос, используя функцию ANY_VALUE() для столбцов с недетерминированными значениями.

источник: https://dev.mysql.com/doc/refman/8.0/en/group-by-modifiers.html

У вас есть две возможности:

1.) Добавить столбцы q.nome, q.nif и q.num_mecanografico в GROUP BY.

2.) Вы можете использовать CASE WHEN для установки значения NULL в последнем ряду (где q.id_socio равно NULL):

SELECT q.id_socio,
  CASE WHEN q.id_socio IS NULL THEN NULL ELSE q.nome END AS nome, 
  CASE WHEN q.id_socio IS NULL THEN NULL ELSE q.nif END AS nif,
  CASE WHEN q.id_socio IS NULL THEN NULL ELSE q.num_mecanografico END AS num_mecanografico,
  SUM(IFNULL(qt.quota_nova, quota)) AS 'quota'
FROM 
    (SELECT id_socio, quota_nova FROM QUOTAS_TEMPORARIAS WHERE ANO = 2019 AND MES = 10) 
    AS qt 
RIGHT JOIN 
    (SELECT id_socio, nome, nif, num_mecanografico, quota FROM SOCIO s, TIPO_PAGAMENTO tp, AGRUPAMENTO a, ORGANIZACAO o WHERE s.ID_TIPO_PAGAMENTO = tp.ID_TIPO_PAGAMENTO AND s.id_agrupamento = a.id_agrupamento AND a.id_organizacao = o.id_organizacao AND o.id_organizacao = 1 AND s.id_tipo_pagamento = 1) 
    AS q
ON q.id_socio = qt.id_socio 
GROUP BY q.id_socio WITH ROLLUP 
HAVING q.nome IS NOT NULL AND q.nif IS NOT NULL AND q.num_mecanografico IS NOT NULL OR q.id_socio IS NULL

демо на dbfiddle.uk

...