2017-02-05 5 views
0

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

-id

-arrived

-released

Использование прибывших и освобождаемых столбцы, я хотел бы Переберите дни месяца, говорят '2017-01-01' через '2017-01-30' и проверьте, сколько продуктов было «активным». Это означает, что по существу цикл будет каждый день для диапазона дат и проверять, сколько продуктов было активным для «2017-01-01» и т. Д. Для каждого дня в диапазоне дат.

Код, который я использую для проверки на определенный день, например «2017-01-01», выглядит следующим образом.

SELECT COUNT(id) 
FROM products_booking 
WHERE (released IS NULL OR released >= '2017-01-01') AND (arrived <= '2017-01-01') 

В этот день будет возвращено количество активных продуктов.

Я хотел бы, однако, выполнить это в определенном диапазоне дат для отчета, который сможет подсчитывать количество «активных» продуктов за каждый день в указанном диапазоне дат.

Я пробовал следующее безрезультатно, и кажется, что с этим подходом я пошел по неверному пути.

SELECT MonthDate.Date, COALESCE(COUNT(IB.id), 0) AS Total 
FROM (
    SELECT 1 AS Date UNION ALL 
    SELECT 2 UNION ALL 
    SELECT 3 UNION ALL 
    SELECT 4 UNION ALL 
    SELECT 5 UNION ALL 
    SELECT 6 UNION ALL 
    SELECT 7 UNION ALL 
    SELECT 8 UNION ALL 
    SELECT 9 UNION ALL 
    SELECT 10 UNION ALL 
    SELECT 11 UNION ALL 
    SELECT 12 UNION ALL 
    SELECT 13 UNION ALL 
    SELECT 14 UNION ALL 
    SELECT 15 UNION ALL 
    SELECT 16 UNION ALL 
    SELECT 17 UNION ALL 
    SELECT 18 UNION ALL 
    SELECT 19 UNION ALL 
    SELECT 20 UNION ALL 
    SELECT 21 UNION ALL 
    SELECT 22 UNION ALL 
    SELECT 23 UNION ALL 
    SELECT 24 UNION ALL 
    SELECT 25 UNION ALL 
    SELECT 26 UNION ALL 
    SELECT 27 UNION ALL 
    SELECT 28 UNION ALL 
    SELECT 29 UNION ALL 
    SELECT 30 UNION ALL 
    SELECT 31) AS MonthDate 
LEFT JOIN products AS IB 
ON MonthDate.Date >= DAY(IB.released) AND MonthDate.Date <= DAY(IB.arrived) 
WHERE MonthDate.Date <= DAY(LAST_DAY('2017-01-30')) 
GROUP BY MonthDate.Date 

Я также пробовал это, но он возвращает «1» на каждый день.

SELECT COUNT(*) cnt, MonthDate.Date 
FROM (
    SELECT 1 AS Date UNION ALL 
    SELECT 2 UNION ALL 
    SELECT 3 UNION ALL 
    SELECT 4 UNION ALL 
    SELECT 5 UNION ALL 
    SELECT 6 UNION ALL 
    SELECT 7 UNION ALL 
    SELECT 8 UNION ALL 
    SELECT 9 UNION ALL 
    SELECT 10 UNION ALL 
    SELECT 11 UNION ALL 
    SELECT 12 UNION ALL 
    SELECT 13 UNION ALL 
    SELECT 14 UNION ALL 
    SELECT 15 UNION ALL 
    SELECT 16 UNION ALL 
    SELECT 17 UNION ALL 
    SELECT 18 UNION ALL 
    SELECT 19 UNION ALL 
    SELECT 20 UNION ALL 
    SELECT 21 UNION ALL 
    SELECT 22 UNION ALL 
    SELECT 23 UNION ALL 
    SELECT 24 UNION ALL 
    SELECT 25 UNION ALL 
    SELECT 26 UNION ALL 
    SELECT 27 UNION ALL 
    SELECT 28 UNION ALL 
    SELECT 29 UNION ALL 
    SELECT 30 UNION ALL 
    SELECT 31) AS MonthDate 
LEFT OUTER JOIN products IB 
ON (MonthDate.date BETWEEN IB.arrived AND IB.released) 
GROUP BY MonthDate.Date; 

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

дата общая

2017-01-01 3024

2017-01-02 3029

....

2017-01-30 2987

Любое другое предложения?

+0

Можете ли вы показать нам свой ожидаемый результат? –

+0

Я добавил ожидаемый результат в редактирование. Надеюсь, это поможет. – Ethan

+0

Еще один вопрос: каков ваш текущий выход? Ваш запрос выглядит хорошо для меня. –

ответ

1

Для получения информации о генерации диапазонов дат см. this question; для вас должен работать тот же подход. Я не могу проверить на данный момент, но это будет выглядеть примерно так:

SET @date_min = '2017-01-01'; 
SET @date_max = '2017-01-31'; 

SELECT 
    dg.date, 
    COUNT(pb.id) as daily_count 
from (
    select DATE_ADD(@date_min, INTERVAL (@i:[email protected]+1)-1 DAY) as `date` 
    from information_schema.columns,(SELECT @i:=0) gen_sub 
    where DATE_ADD(@date_min,INTERVAL @i DAY) BETWEEN @date_min AND @date_max 
) date_generator dg 
left join products_booking pb on (pb.released IS NULL OR pb.released >= dg.date) AND (pb.arrived <= dg.date) 
GROUP BY dg.date 
ORDER BY dg.date 
; 
+0

Это работает именно так, как нужно. Спасибо! – Ethan

Смежные вопросы