Как получить счетчик 0, если в базе данных нет данных, использующих mySQL - PullRequest
5 голосов
/ 17 июня 2019

Я показываю ежемесячный пользователь, зарегистрированный в моем приложении. Для этого я использовал приведенный ниже запрос, который работает нормально. Но с этим запросом, если ни один пользователь не зарегистрирован в июне, то нет данных против июня. Я хочу строку с месяцем июнь и всей другой информацией, установленной на 0. Может кто-нибудь помочь мне с этим?

SELECT Month(createdon), count(*) as users,COUNT(if(roleid=1,1,NULL)) as instructor, COUNT(if(roleid=2,1,NULL)) as student FROM user_profile where Year(createdon) = Year(Now()) group by MONTH(createdon);

Я получаю вывод как:

Month(created on) | users | instructor | student | 3 | 4 | 3 | 1 | 4 | 7 | 5 | 2 |

Здесь 3 и 4 месяц соответствуют марту и апрелю соответственно.

Но фактический результат:

Month(created on) | users | instructor | student | 1 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 3 | 4 | 3 | 1 | 4 | 7 | 5 | 2 | 5 | 0 | 0 | 0 | 6 | 0 | 0 | 0 |

Ответы [ 5 ]

1 голос
/ 17 июня 2019

Вы можете попробовать это:

SELECT MONTH(createdon) AS month, COUNT(*) AS users, COUNT(IF(roleid=1,1,NULL)) AS instructor, COUNT(IF(roleid=2,1,NULL)) AS student
FROM user_profile
WHERE (YEAR(createdon) = YEAR(NOW()))
GROUP BY MONTH(createdon)
UNION
SELECT M.month, 0, 0, 0
FROM (SELECT 1 AS month UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) AS M
WHERE (M.month <= MONTH(NOW()))
  AND (NOT EXISTS (SELECT * FROM user_profile WHERE (MONTH(createdon) = M.month)));
1 голос
/ 17 июня 2019

У меня был такой же опыт Так что просто используйте

SELECT IF( EXISTS (SELECT * FROM user_profile WHERE MONTH(createdon)= 'yourmonth')
  ,SELECT 
     Month(createdon),
     COUNT(*) AS users,
     COUNT(if(roleid=1,1,NULL)) AS instructor, 
     COUNT(if(roleid=2,1,NULL)) AS student 
  FROM user_profile 
  WHERE Year(createdon) = Year(Now()) 
  Group BY MONTH(createdon)
,0)
0 голосов
/ 17 июня 2019

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

SELECT m.mon, COUNT(up.createdon) as users,
       SUM(up.roleid = 1) as instructor,  
       SUM(up.roleid = 2) as student
FROM (SELECT 1 as mon UNION ALL
      SELECT 2 as mon UNION ALL
      SELECT 3 as mon UNION ALL
      SELECT 4 as mon UNION ALL
      SELECT 5 as mon UNION ALL
      SELECT 6 as mon 
     ) m LEFT JOIN
     user_profile up
     ON m.mon = MONTH(up.createdon) AND
        YEAR(createdon) = YEAR(Now()) 
GROUP BY m.mon;

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

0 голосов
/ 17 июня 2019

Вы не видите row with 0 value, потому что в вашей таблице нет данных за данный месяц, и в groupby будут отображаться данные о наличии месяцев.

Вы можете создать список месяцев для данного года -

select  TO_CHAR((current_date - interval '1 month' * a),'MM') AS mm FROM generate_series(1,12,1) AS s(a)

он сгенерирует значение наподобие

01
02
03
.
.

Затем вы можете написать подзапрос с этой таблицей и выполнить left join with your user_profile таблицу, и вы получите данные, как вы указали.

Для получения дополнительной информации перейдите по этой ссылке .

0 голосов
/ 17 июня 2019

Вы можете собрать отсортированный результат SQL и выполнить итерацию настраиваемого диапазона и вставить либо данные, либо пустой набор результатов.

function getRange(from, to, result) {
    var i, j = 0;
    for (i = from; i <= to; i++) {
        if (result[j] && i === result[j][0]) {
            console.log(...result[j++]);       // slq result
        } else {
            console.log(i, 'empty row');       // row with zeroes
        }
    }
}

getRange(1, 6, [[3, 2, 5], [4, 3, 2]]);
...