2010-02-16 3 views
6

данные:Как получить значения на каждый день в течение месяца

values date 
14 1.1.2010 
20 1.1.2010 
10 2.1.2010 
7 4.1.2010 
... 

образец запроса о январе 2010 г. должен получить 31 строк. Один на каждый день. И значения должны быть добавлены. Сейчас я могу сделать это с 31 запросом, но я хотел бы, чтобы это работало с одним. Является ли это возможным?

результаты:

1. 34 
2. 10 
3. 0 
4. 7 
... 
+0

Добро пожаловать в SO ivar. Я думаю, вам нужно добавить более подробную информацию о том, что вы запрашиваете и как? –

+0

Нам потребуется более подробная информация ... на каком языке вы используете? Какая система это? – Mala

+0

Какова ваша колонка даты? Это ДАТА или VARCHAR? –

ответ

10

Это на самом деле удивительно сложно сделать в SQL. Один из способов сделать это, чтобы иметь длинный отборное заявление с накидной Alls генерировать число от 1 до 31. Это демонстрирует принцип, но я остановился на 4 для ясности:

SELECT MonthDate.Date, COALESCE(SUM(`values`), 0) AS Total 
FROM (
    SELECT 1 AS Date UNION ALL 
    SELECT 2 UNION ALL 
    SELECT 3 UNION ALL 
    SELECT 4 UNION ALL 
    -- 
    SELECT 28 UNION ALL 
    SELECT 29 UNION ALL 
    SELECT 30 UNION ALL 
    SELECT 31) AS MonthDate 
LEFT JOIN Table1 AS T1 
ON MonthDate.Date = DAY(T1.Date) 
AND MONTH(T1.Date) = 1 AND YEAR(T1.Date) = 2010 
WHERE MonthDate.Date <= DAY(LAST_DAY('2010-01-01')) 
GROUP BY MonthDate.Date 

Было бы лучше использовать таблицу, чтобы сохранить эти значения и присоединиться к ней.

Результат:

1, 34 
2, 10 
3, 0 
4, 7 
5

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

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

Таким образом, вы могли бы:

CREATE TABLE Calendar (
    label varchar, 
    cal_date date, 
    primary key (cal_date) 
) 

запрос:

SELECT 
    c.label, 
    SUM(d.values) 
FROM 
    Calendar c 
JOIN 
    Data_table d 
ON d.date_field = c.cal_date 
WHERE 
    c.cal_date BETWEEN '2010-01-01' AND '2010-01-31' 
GROUP BY 
    d.date_field 
ORDER BY 
    d.date_field 

Update:

я вижу, у вас есть DateTimes, а не даты. Вы могли бы просто использовать функцию MySQL DATE() в соединении, но это, вероятно, не было бы оптимальным. Другим подходом было бы иметь время начала и окончания в таблице календаря, определяющее «ведро времени» для каждого дня.

0

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

SELECT COUNT(value_column) FROM table WHERE date_column LIKE '2010-01-%' GROUP BY date_column 
+0

date_column не установлен когда-то – NineCattoRules

+1

@NineCattoRules Если вы не OP из семи лет назад, я не знаю, как вы это узнаете. Если это так, запрос может быть легко изменен для настройки. – ceejayoz

+0

в вопросе «... для каждого дня ...», а в «результатах» (из ОП) есть «3. 0' – NineCattoRules

1

Для динамического получения даты в диапазоне дат с помощью SQL вы можете сделать это (пример в MySQL):

Создать таблицу для хранения номера 0 через 9.

CREATE TABLE ints (i tinyint(4)); 

insert into ints (i) 
values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); 

Выполнить запрос следующим образом:

select ((curdate() - interval 2 year) + interval (t.i * 100 + u.i * 10 + v.i) day) AS Date 
from 
    ints t 
    join ints u 
    join ints v 
having Date between '2015-01-01' and '2015-05-01' 
order by t.i, u.i, v.i 

Это произведет все даты между 1 января 2015 года и 1 мая 2015 года.

Output 
2015-01-01 
2015-01-02 
2015-01-03 
2015-01-04 
2015-01-05 
2015-01-06 
... 
2015-05-01 

Запрос объединяет таблицу ints 3 раза и получает добавочное число (от 0 до 999). Затем он добавляет это число как дневной интервал, начиная с определенной даты, в этом случае дата 2 года назад. Любой диапазон дат от 2 лет назад и 1000 дней вперед можно получить с помощью приведенного выше примера. Чтобы создать запрос, который генерирует даты более 1000 дней, просто присоединитесь к таблице ints, чтобы разрешить до 10 000 дней диапазона и т. Д.

1

Это работает для меня ... Его модификация запроса, который я нашел на другом сайте. Предложение «INTERVAL 1 MONTH» гарантирует получение данных текущего месяца, включая нули в течение нескольких дней, у которых нет хитов. Измените это на «INTERVAL 2 MONTH», чтобы получить данные за прошлые месяцы и т. Д.

У меня есть таблица, называемая «полезная нагрузка» с помощью столбца «timestamp» - Im, затем соединяющая столбец timestamp с динамически сгенерированными датами, так что даты совпадают в предложении ON.


SELECT `calendarday`,COUNT(P.`timestamp`) AS `cnt` FROM 
(SELECT @tmpdate := DATE_ADD(@tmpdate, INTERVAL 1 DAY) `calendarday` 
    FROM (SELECT @tmpdate := 
     LAST_DAY(DATE_SUB(CURDATE(),INTERVAL 1 MONTH))) 
     AS `dynamic`, `payload`) AS `calendar` 
LEFT JOIN `payload` P ON DATE(P.`timestamp`) = `calendarday` 
GROUP BY `calendarday` 
Смежные вопросы