Группировка по месяцам sql: delphi — Группировка по месяцам даты SQL
Содержание
sql server — sql-запрос агрегированных данных таблицы по месяцам
Вопрос задан
Изменён
1 год 8 месяцев назад
Просмотрен
844 раза
Здравствуйте. Объясню, что мне нужно, на примере. Дана таблица:
Мне нужен такой запрос, чтобы получилось следующее:
То есть мне нужен столбец количества пользователей, у которых совпадает сайт магазина, продукт и месяц покупки. Если я правильно понимаю, GROUP BY выводит совпадение по дням, а мне надо по месяцам. Чувствую, что ответ на поверхности, нуждаюсь в вашей помощи.
- sql
- sql-server
4
Если вы не справляетесь сразу со сложным запросом — попробуйте разбить проблему на несколько частей и решать их по очереди. Для начала, определить, как именно получить месяц из даты.
Понятно, что просто извлечь месяц недостаточно, т.к. месяц этого года будет равен месяцу прошлого, а это, по всей видимости, не то, чего вы хотите. Как добавить год, вам подсказали в комментариях.
После того, как получили правильный месяц, делайте группировку.
Если я правильно понял, какого результата вы пытаетесь добиться, предполагаю, что ваш итоговый запрос будет выглядеть так:
select [Сайт магазина] , [Продукт] , cast(year([День покупки]) as varchar(10)) + '-' + cast(month([День покупки]) as varchar(10)) as [Месяц покупки] , count(distinct [Имя пользователя]) as [Количество аккаунтов] from [Таблица] group by [Сайт магазина] , [Продукт] , cast(year([День покупки]) as varchar(10)) + '-' + cast(month([День покупки]) as varchar(10))
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Группировка данных по месяцу при выборке по date | PHPClub
KorP
Новичок
#1
Группировка данных по месяцу при выборке по date
есть — БД дата/запись, дата хранится как date, задача — группировать записи при выводе по месяцу.
#2
Привести к виду месяц/Год
по нему и групировать
DATE_FORMAT()
KorP
Новичок
#3
дата приведена к виду дд.
#4
http://www.mysql.ru/docs/man/Date_and_time_functions.html
KorP
Новичок
#5
Mr_Max
и? читал я это, только я не знаю что из этого и как работает с GROUP BY
вот привожу запрос:
PHP:
SELECT *, DATE_FORMAT(date, '%d.![]()
- #6
дата приведена к виду дд.мм.гггг в самом sql запросе, как по ней группировать то? GROUP BY date ничего не даёт...вот и спрашиваю...надо как то месяц указать...но как - в мане не нашёл
Нажмите для раскрытия...
GROUP BY DATE_FORMAT...
или
GROUP BY SUBSTRING....
KorP
Новичок
- #7
Mr_Max
но ведь не обязательно использовать DATE_FORMAT? месяц в любом случае будет вторым двухзначным значением, в моём случае (как он хранится в БД и как он выводится пользователю)
но вот сгруппировать записи что то так и не получается
если использовать GROUP BY DATE_FORMAT(date, '%m'), выводится только 1-я запись в таблице, тоже самое и при использовании GROUP BY MONTH(date)
Mr_Max
Первый класс.

- #8
KorP
Может следует перечитать что делает групировка?
выводится только 1-я запись в таблице, тоже самое и при использовании GROUP BY MONTH(date)
Нажмите для раскрытия...
Обясните словами что Вам нужно.
KorP
Новичок
- #9
есть в БД:
дд.
- #10
KorP
дд.мм.гггг/текст
дд.мм.гггг/текст
дд.мм.гггг/текст
дд.мм.гггг/текст
надо:
мм
дд - текст
дд - текст
дд - текст
дд - текстНажмите для раскрытия...
Простите, каким боком сюда групировка?
KorP
Новичок
- #11
"MySQL позволяет разбивать записи результирующего набора на определённые группы на основании определённого атрибута"
а почему нет собственно? дата (часть даты) является атрибутом, по которому происходит группировка данных.
- #12
выводится только 1-я запись в таблице, тоже самое и при использовании GROUP BY MONTH(date)
Нажмите для раскрытия...
С этого места, пожалуйста, пододробнее что Вы хотите зделать.
-~{}~ 22.06.07 17:42:
MySQL позволяет разбивать записи результирующего набора на определённые группы на основании определённого атрибута
Нажмите для раскрытия...
групируете по месяцу - получаете 12 записей
по дням - 31....
по мес-год - получаете по 1-й записи что соотвествует ***ОДНОМУ ДНЮ*** каждого месяца соотвествующего года, что есть в БД
Вы как-то по другому себе представляете групировку?
-~{}~ 22. 06.07 17:47:
немного непонятно написал.
изменения в ****
KorP
Новичок
- #13
Автор оригинала: Mr_Max
по мес-год - получаете по 1-й записи что соотвествует ***ОДНОМУ ДНЮ*** каждого месяца соотвествующего года, что есть в БДНажмите для раскрытия...
что то я н пойму - почему при групировке записей я получу ОДНУ запись если у меня записей за этот месяц к примеру 10?
Mr_Max
Первый класс.

- #14
что то я н пойму - почему при групировке записей я получу ОДНУ запись если у меня записей за этот месяц к примеру 10?
Нажмите для раскрытия...
Потому-что сгрупированно по год-мес
Возникают ещё вопросы?
Возможно следует перечитать мануал?
http://www.mysql.ru/docs/man/Group_by_functions.html
-~{}~ 22.06.07 19:51:
задача - группировать записи при выводе по месяцу
Нажмите для раскрытия...
что вы здесь имеете ввиду?
-~{}~ 22. 06.07 19:55:
Пожалуйста, словами и предложениями, а то мне кажется вы чего-то недоговариваете.
ПРимер:
я хочу выбрать из таблицы, в которой хранится то-то и то, чтоб...
KorP
Новичок
- #15
Автор оригинала: Mr_Max
Потому-что сгрупированно по год-месНажмите для раскрытия...
ну сгруппировано по год-мес, но если записей за этот год-мес 10-20-... почему выводится только одна то???? что то я читая ман не могу понять ваших слов
Автор оригинала: Mr_Max
Пожалуйста, словами и предложениями, а то мне кажется вы чего-то недоговариваете.
![]()
- #16
я уже написал словами пример?
Нажмите для раскрытия...
Вы сами то пробовали понять что написали?
дд.мм.гггг/текст
дд.мм.гггг/текст
дд.мм.гггг/текст
дд.мм.гггг/текст
надо:
мм
дд - текст
дд - текст
дд - текст
дд - текстНажмите для раскрытия...
ну и групировка (мускула) Вам совсем не нужна.
Обычный запрос с сортировкой по нужным критериям
и 1-м условием при выводе.![]()
KorP
Новичок
- #17
Mr_Max
вполне понял - в мане дата указана именно так - дд.мм.гггг, так что я написал несколько строк Бд и как эти несколько строк должны выводиться пользователю. по-моему всё доступно написано, в стиле мануалаобычный запрос это SELECT * FROM afisha ORDER BY date (упростил что б не писать километры каждый раз) что ли? как при выборке организовать группировку данных по месяцам?
Mr_Max
Первый класс.
![]()
- #18
Что-то типа такого
PHP:
while($data = ..........){ if (!isset ($flag[$data['date']])) { echo 'дата в виде июнь 2007'; $flag[$data['date']] = true; } ............... Дальше обычный вывод афиши за числа месяца; ............... }Вроде так.
KorP
Новичок
#19
Mr_Max
под все 12 месяцев писать?
Mr_Max
Первый класс.
#20
KorP
Нет
Неужели так сложно подумать?
Как сгруппировать по месяцам с помощью SQL Server?
спросил
Изменено
1 год, 1 месяц назадПросмотрено
141 тысяч разУ меня есть таблица с этой схемой
ItemID UserID Year IsPaid PaymentDate Amount 1 1 20090 01.11.2009 300 2 1 2009 0 01.12.2009 342 3 1 2010 0 01.01.2010 243 4 1 2010 0 01.02.2010 2543 5 1 2010 0 01.03.2010 475
Я пытаюсь заставить работать запрос, который показывает итоги за каждый месяц. До сих пор я пробовал DateDiff и вложенные выборки, но ни один из них не дает мне того, что я хочу. Это самое близкое, что я думаю:
DECLARE @start [datetime] = 2010/4/1; ВЫБЕРИТЕ ItemID, IsPaid, (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 и DateDiff (m, PaymentDate, @start) = 0 И UserID = 100) КАК «Апр», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 1 И UserID = 100) КАК «Май», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 2 И UserID = 100) КАК «Июнь», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 3 И UserID = 100) КАК «июль», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 4 И UserID = 100) КАК «Авг», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 5 И UserID = 100) КАК «Сентябрь», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 6 И UserID = 100) КАК «Октябрь», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 7 И UserID = 100) КАК «Ноябрь», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 8 И UserID = 100) КАК «Dec», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 9И UserID = 100) КАК "Ян", (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 10 И UserID = 100) КАК «Фев», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И DateDiff (m, PaymentDate, @start) = 11 И UserID = 100) КАК «Мар» FROM LIVE L INNER JOIN Payments I ON I.LiveID = L.RECORD_KEY ГДЕ UserID = 16178
Но я просто получаю нули, когда должен получать значения. Я что-то упускаю?
- sql
- sql-сервер-2008
- датадифф
3
SELECT CONVERT(NVARCHAR(10), PaymentDate, 120) [Месяц], SUM(Сумма) [TotalAmount] ОТ Платежи ГРУППИРОВАТЬ ПО ПРЕОБРАЗОВАНИЮ (NVARCHAR (10), PaymentDate, 120) ЗАКАЗАТЬ ПО [Месяц]Вы также можете попробовать:
SELECT DATEPART(Year, PaymentDate) Year, DATEPART(Month, PaymentDate) Month, SUM(Amount) [TotalAmount] ОТ Платежи ГРУППА ПО DATEPART(Год, Дата платежа), DATEPART(Месяц, Дата платежа) Сортировать по году, месяцу1
Ограничение размера NVARCHAR до 7, передаваемого в CONVERT для отображения только «ГГГГ-ММ»
SELECT CONVERT(NVARCHAR(7),PaymentDate,120) [Месяц], SUM(Amount) [TotalAmount] ОТ Платежи ГРУППА ПО ПРЕОБРАЗОВАНИЮ (NVARCHAR (7), PaymentDate, 120) ЗАКАЗАТЬ ПО [Месяц]Я предпочитаю комбинировать
DATEADD
иDATEDIFF
, например:Вместе эти две функции обнуляют компонент даты , меньший , чем указанный datepart (т.
е.
МЕСЯЦ
в этом примере).Вы можете изменить бит даты на
YEAR
,WEEK
,DAY
и т. д., что очень удобно.Ваш первоначальный SQL-запрос будет выглядеть примерно так (я не могу проверить его, так как у меня нет вашего набора данных, но он должен указать вам правильный путь).
DECLARE @start [datetime] = '2010-04-01'; ВЫБРАТЬ ID товара, ID пользователя, DATEADD(МЕСЯЦ,DATEDIFF(МЕСЯЦ, 0, Создано),0) [Месяц], Оплачивается, СУММА(Сумма) ИЗ ЖИВОГО Л INNER JOIN Платежи I ON I.LiveID = L.RECORD_KEY ГДЕ UserID = 16178 И Дата платежа > @startЕще одна вещь: столбец
Month
вводится какDateTime
, что также является хорошим преимуществом, если вам нужно дополнительно обработать эти данные или, например, отобразить их объект .NET.Если вам нужно делать это часто, я бы, вероятно, добавил вычисляемый столбец
PaymentMonth
в таблицу:ALTER TABLE dbo.Payments ADD PaymentMonth AS MONTH(PaymentDate) PERSISTED
Он сохраняется и хранится в таблице, поэтому его запросы не снижают производительность. Это 4-байтовое значение INT, так что накладные расходы также минимальны.
Если у вас есть это, вы можете упростить свой запрос, чтобы он выглядел примерно так:
SELECT ItemID, IsPaid, (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И PaymentMonth = 1 И UserID = 100) КАК «Янв», (ВЫБЕРИТЕ СУММУ (сумму) ИЗ платежей, ГДЕ Год = 2010 И PaymentMonth = 2 И UserID = 100) КАК «Фев», .... и так далее ..... ИЗ ЖИВОГО Л INNER JOIN Платежи I ON I.LiveID = L.RECORD_KEY ГДЕ UserID = 161781
DECLARE @start [datetime] = 2010/4/1;Должно быть…
DECLARE @start [datetime] = '2010-04-01';У вас есть деление 2010 года на 4, затем на 1, а затем преобразование в дату. Это 57,5-й день с 01 января 1900 года.
Попробуйте
SELECT @start
после инициализации, чтобы проверить, правильно ли это.Другой подход, который не требует добавления столбцов к результату, заключается в простом обнулении компонента даты
дня
, поэтому2016-07-13
и2016-07-16
оба будут равны2016-07-01
, что сделает их равными по месяцам.Если у вас есть значение даты
(не
datetime
), вы можете обнулить его напрямую:SELECT DATEADD(день, 1 - DATEPART(день, [Дата]), [Дата]), СЧИТАТЬ(*) ИЗ [Стол] ГРУППА ПО DATEADD(день, 1 - DATEPART(день, [Дата]), [Дата])Если у вас есть значения
datetime
, вам нужно будет использоватьCONVERT
, чтобы удалить часть времени суток:ВЫБЕРИТЕ DATEADD(день, 1 - DATEPART(день, [Дата]), CONVERT(дата, [Дата])), СЧИТАТЬ(*) ИЗ [Стол] ГРУППА ПО DATEADD(день, 1 - DATEPART(день, [Дата]), CONVERT(дата, [Дата]))Теперь ваш запрос явно просматривает платежи только за год = 2010, однако я думаю, что вы хотели, чтобы ваши январь/февраль/март фактически представляли 2009 год.
Если это так, вам нужно немного скорректировать это для этого случая. Не запрашивайте значения суммы для каждого столбца, а только условие разницы дат в месяцах. Поместите остальное в предложение WHERE.
ВЫБОР SUM(случай, когда DateDiff(m, PaymentDate, @start) = 0 затем Сумма еще 0 конец ) КАК "Апр", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 1 затем сумма еще 0 конец ) КАК "май", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 2 затем Сумма еще 0 конец ) КАК "Июнь", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 3 затем Сумма еще 0 конец ) КАК "июль", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 4 затем Сумма еще 0 конец ) КАК "Авг", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 5 затем Сумма еще 0 конец ) КАК "Сентябрь", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 6 затем Сумма еще 0 конец ) КАК "Октябрь", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 7 затем Сумма еще 0 конец ) AS "Nov", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 8 затем Сумма еще 0 end ) AS "Dec", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 9затем Сумма еще 0 конец ) КАК "Ян", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 10 затем Сумма еще 0 конец ) КАК "февраль", SUM(случай, когда DateDiff(m, PaymentDate, @start) = 11 затем Сумма еще 0 конец ) КАК "март" ИЗ Платежи I ПРИСОЕДИНЯЙТЕСЬ к Live L на I.LiveID = L.Record_Key КУДА Год = 2010 И UserID = 100
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Sql Group By Month Names — Примеры запросов
3 года назад
от Thomas Brown
1 588 Просмотров
Чтобы сгруппировать запросы по названию месяца, мы должны использовать функцию datename в sql.
Эта функция получает два параметра. Первый — интервал; для названий дней мы должны писать dw, для названий месяцев мы должны писать m или mm. Второй параметр — это параметр даты. Если нам нужен только индекс месяца, мы также можем использовать функцию месяца.
Давайте сделаем пример с базой данных библиотеки
Примеры из базы данных библиотеки
Пример 1 :Список количества учащихся, родившихся каждый месяц.
Transact-SQL
Выберите DateName(мм,дата рождения) как MName,count(*) как Count от студентов
группировка по DATEName(мм,дата рождения)
Выберите DateName(мм,дата рождения) как MName,количество(*) как Count из студентов
группировать по DATEName(мм,дата рождения)
Результаты запроса
Пример 2 :Укажите количество учащихся, рожденных каждый месяц, в порядке подсчета.
Transact-SQL
Выберите DateName(мм,дата рождения) как MName,count(*) как Count от студентов
группировка по DATEName(мм,дата рождения)
заказ по количеству
Выберите DateName(mm,дата рождения) как MName,count(*) как Count из студентов
группировать по DATEName(mm,дата рождения)
упорядочить по количеству
Результаты запроса
Пример 3: Перечислите количество студентов Mail, родившихся каждый месяц, в порядке количества.
Transact-SQL
Выберите DateName(мм,дата рождения) как MName,count(*) как Count от студентов
где пол = ‘М’
группировка по DATEName(мм,дата рождения)
заказ по количеству
Выберите DateName(мм,дата рождения) как MName, count(*) как Count от студентов
, где пол = ‘M’
группа по ДАТАИмя(мм,дата рождения)
порядок по количеству
Результаты запроса
Пример 4: Список названий месяцев и количество взятых книг в этом месяце
Transact-SQL
Выберите DATENAME(mm,takenDate) как Месяцы,count(*) как Count from заимствования
сгруппировать по DATENAME(mm,takenDate)
Выберите DATENAME(mm,takenDate) как Months,count(*) как Count from заимствования
группа по DATENAME(mm,takenDate)
Результаты запроса
Пример 5: Список названий месяцев и количество взятых книг в этом месяце, упорядоченное по количеству книг
Transact-SQL
Выберите DATENAME(mm,takenDate) как Months,count(*) как BookCount из займов
сгруппировать по DATENAME(mm,takenDate)
заказать по BookCount
Выберите DATENAME(mm,takenDate) как Months,count(*) как BookCount из заимствований
группа по DATENAME(mm,takenDate)
заказ по BookCount
или
Transact-SQL
Выберите DATENAME(mm,takenDate) как Months,count(*) как BookCount из займов
сгруппировать по DATENAME(mm,takenDate)
заказать по 2
Выберите DATENAME(mm,takenDate) как Months, count(*) как BookCount из заимствований
группировать по DATENAME(mm,takenDate)
упорядочить по 2
Результаты запроса
Пример 6: Список названий месяцев 2011 года и количество взятых книг в этом месяце, упорядоченное по количеству книг
Transact-SQL
Выберите DATENAME(mm,takenDate) как Months,count(*) как BookCount из займов
где год (взятая дата) = 2015
сгруппировать по DATENAME(mm,takenDate)
заказать по BookCount
Выберите DATENAME(mm,takenDate) как Months,count(*) как BookCount из заимствований
где year(takenDate) = 2015
группа по DATENAME(mm,takenDate)
порядок по BookCount
Результаты запроса
Пример 7: Перечислите названия месяцев 2011 года и количество взятых книг в этом месяце, упорядоченное по количеству книг.