Подсчет дат в SQL

У меня есть таблица ниже в MySQL 5.6

ИмяДата началаДата окончания
Первый2021-03-202021-03-21
Второй2021-03-202021-03-23
В третьих2021-03-202021-03-20

Мне нужен запрос в MYSQL, чтобы вывести количество «Имя», которое было живым в каждый день (между StartDate и EndDate) для заданного диапазона дат. Возможно ли это через SQL?

Результат: Допустим, мы даем диапазон как 2021-03-20 и 2021-03-23.

ДатаСчитать
2021-03-203
2021-03-212
2021-03-221
2021-03-231

Версия MySQL ??

Salman A 31.03.2021 12:56

@SalmanA MySQL 5.6

San 31.03.2021 13:01

Продолжай. Попробуй что-нибудь.

Strawberry 31.03.2021 13:02

Тогда вам понадобится таблица календаря ... или создайте список дат через PHP или что-то еще.

Salman A 31.03.2021 13:02
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
1
4
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

--The data table 
DECLARE @dataTable TABLE (Name nvarchar(100), StartDate date, EndDate date)
INSERT INTO @dataTable VALUES('First', '2021-03-20', '2021-03-21')
INSERT INTO @dataTable VALUES('Second', '2021-03-20', '2021-03-23')
INSERT INTO @dataTable VALUES('Third', '2021-03-20', '2021-03-20')
--end

--Create a temporary table with dates in range
DECLARE @dates TABLE(dt date)    
DECLARE @dateFrom date
DECLARE @dateTo date

SET @dateFrom = '2021/03/01'
SET @dateTo = '2021/03/31'

WHILE(@dateFrom < @dateTo)
BEGIN
   SELECT @dateFrom = DATEADD(day, 1,@dateFrom)
   INSERT INTO @dates 
   SELECT @dateFrom
END
--end

--Do the thing
SELECT dt as Date, COUNT(*) as Count
FROM @dates
    inner join @dataTable ON dt >= StartDate and dt <= EndDate
GROUP BY dt
--end

Ваш код специфичен для SQL Server и не может использоваться в MySQL.

Akina 31.03.2021 13:27

@ Акина Не могли бы вы объяснить почему?

orBeat 31.03.2021 13:29

о_О Вы не знаете, что SQL Server (он же MS SQL) и MySQL - это два разных сервера? со своими собственными особенностями синтаксиса, которые в большинстве случаев несовместимы? В данном конкретном случае MySQL не поддерживает в первую очередь анонимные блоки кода.

Akina 31.03.2021 13:56

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

orBeat 31.03.2021 14:07
Ответ принят как подходящий

Один из способов - начать со строки на каждый день, а затем использовать исправленный подзапрос. Допустим, у вас есть календарный стол:

select c.date,
       (select count(*)
        from t
        where c.date between t.startdate and t.enddate
       ) as num_active
from calendar c
where c.date >= '2021-03-20' and c.date3 <= '2021-03-23';

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

select c.date,
       (select count(*)
        from t
        where c.date between t.startdate and t.enddate
       ) as num_active
from (select date( '2021-03-20' + interval (@rn := @rn + 1) day) as date
      from t cross join
           (select @rn := -1) params
     ) c
where c.date >= '2021-03-20' and c.date3 <= '2021-03-23';

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

select c.date,
       (select count(*)
        from t
        where c.date between t.startdate and t.enddate
       ) as num_active
from (select date( '2021-03-20' ) as date union all
      select date( '2021-03-21' ) as date union all
      select date( '2021-03-22' ) as date union all
      select date( '2021-03-23' ) as date
     ) c
where c.date >= '2021-03-20' and c.date3 <= '2021-03-23';

Спасибо! Искал что-то подобное.

San 31.03.2021 14:36

Другие вопросы по теме