Как не вернуть 0 вместо нуля в запросе mysql? - PullRequest
0 голосов
/ 27 января 2020

Следующий запрос возвращает посетителей и просмотров страниц за последние 7 дней. Однако, если нет результатов (скажем, это учетная запись fre sh), ничего не возвращается.

Как отредактировать это, чтобы вернуть 0 в те дни, когда нет записей?

SELECT Date(timestamp)      AS day, 
       Count(DISTINCT hash) AS visitors, 
       Count(*)             AS pageviews 
FROM   behaviour 
WHERE  company_id = 1
       AND timestamp >= Subdate(Curdate(), 7) 
GROUP  BY day 

Ответы [ 4 ]

0 голосов
/ 27 января 2020

Вы можете использовать следующий трюк:

  1. Сначала получите запрос, который возвращает 1 фиктивную строку: SELECT 1;
  2. Затем используйте LEFT JOIN для соединения итоговых строк без условий , Это объединение вернет значения в случае, если в других случаях существуют данные со значениями NULL.
  3. Последний выбор из объединенных запросов только то, что нам нужно, и преобразование значений NULL в нули с использованием функции IFNULL.

    SELECT 
        IFNULL(b.day,0) AS DAY,
        IFNULL(b.visitors,0) AS visitors,
        IFNULL(b.pageviews,0) AS pageviews
    FROM (
        SELECT 1
    ) a
    LEFT JOIN (
        SELECT DATE(TIMESTAMP)      AS DAY, 
           COUNT(DISTINCT HASH) AS visitors, 
           COUNT(*)             AS pageviews 
        FROM   behaviour 
        WHERE  company_id = 1
           AND TIMESTAMP >= SUBDATE(CURDATE(), 7) 
        GROUP  BY DAY 
    ) b ON 1 = 1;
    
0 голосов
/ 27 января 2020

Использовать IFNULL:

IFNULL (expr1, 0)

Из документации:

Если expr1 не равен NULL, IFNULL () возвращает expr1; в противном случае возвращается expr2. IFNULL () возвращает> число c или строковое значение, в зависимости от контекста, в котором оно используется.

0 голосов
/ 27 января 2020

Используйте запрос, который возвращает все даты с сегодняшнего дня минус 7 дней до сегодняшнего дня и оставляет присоединение к таблице поведения:

SELECT t.timestamp            AS day, 
       Count(DISTINCT b.hash) AS visitors, 
       Count(b.timestamp)     AS pageviews 
FROM (
  SELECT Subdate(Curdate(), 7) timestamp UNION ALL SELECT Subdate(Curdate(), 6) UNION ALL 
  SELECT Subdate(Curdate(), 5) UNION ALL SELECT Subdate(Curdate(), 4) UNION ALL SELECT Subdate(Curdate(), 3) UNION ALL 
  SELECT Subdate(Curdate(), 2) UNION ALL SELECT Subdate(Curdate(), 1) UNION ALL SELECT Curdate()
) t LEFT JOIN behaviour b 
ON Date(b.timestamp) = t.timestamp AND b.company_id = 1
GROUP BY day
0 голосов
/ 27 января 2020

Предполагая, что у вас всегда есть хотя бы одна запись в таблице для каждого из последних 7 дней (независимо от company_id), вы можете использовать условное агрегирование следующим образом:

select 
    date(timestamp) as day, 
    count(distinct case when company_id = 1 then hash end) as visitors, 
    sum(company_id = 1) as pageviews 
from behaviour 
where timestamp >= curdate() - interval 7 day
group by day 

Примечание что я изменил ваш запрос, чтобы использовать стандартную арифметику даты, которая, как мне кажется, легче понять, что функции даты.

В противном случае вам нужно было бы переместить условие даты из предложения where в агрегатные функции:

select 
    date(timestamp) as day, 
    count(distinct case when timestamp >= curdate() - interval 7 day and company_id = 1  then hash end) as visitors, 
    sum(timestamp >= curdate() - interval 7 day and company_id = 1) as pageviews 
from behaviour 
group  by day 

Если ваша таблица большая, это может быть дорого, поэтому я бы не советовал.

Кроме того, вы можете сгенерировать производную таблицу дат и left join с оригиналом запрос:

select
    curdate - interval x.n day day,
    count(distinct b.hash) visitors,
    count(b.hash) page_views
from (
    select 1 n union all select 2 union all select 3 union all select 4
    union all select 5 union all select 6 union all select 7
) x
left join behavior b
    on  b.company_id = 1
    and b.timestamp >= curdate() - interval x.n day
    and b.timestamp < curdate() - interval (x.n - 1) day 
 group by x.n
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...