SQL Server: выберите разные выходные данные в формате mon-yyyy в порядке убывания - PullRequest
4 голосов
/ 30 апреля 2011

У меня есть datetime столбец в таблице со следующими данными:

2011-03-23
2011-04-19
2011-04-26
2011-05-26

Я хочу выбрать различный вывод формата mon-yyyy, упорядоченный по убыванию даты отчета. Нам нужно выбрать только один столбец в операторе SQL

Этот SQL работает, но я хочу заказать по ReportDate колонке

SELECT  distinct SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
        SUBSTRING (convert(varchar, ReportDate, 100),8,4 ) 
  FROM [EnvelopsDB].[dbo].[Envelopes]

выход

Apr-2011
Mar-2011
May-2011

Этот SQL выдает ошибку:

SELECT  distinct SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
        SUBSTRING (convert(varchar, ReportDate, 100),8,4 ) 
  FROM [EnvelopsDB].[dbo].[Envelopes]
  order by ReportDate

Error

Сообщение 145, Уровень 15, Состояние 1, Строка 2
Элементы ORDER BY должны появляться в списке выбора, если SELECT DISTINCT указано.

Какой лучший запрос SQL для получения нужного мне результата?

Ответы [ 4 ]

5 голосов
/ 30 апреля 2011
with testdata as
(
  select cast('2011-03-23' as datetime) as d
union all
  select cast('2011-04-19' as datetime)
union all
  select cast('2011-04-26' as datetime)
union all
  select cast('2011-05-26' as datetime)
)
SELECT DATENAME(month,d)+'-'+DATENAME(year,d)
FROM testdata
GROUP BY DATEPART(year,d), DATEPART(month,d), DATENAME(month,d),DATENAME(year,d)
ORDER BY DATEPART(year,d), DATEPART(month,d)

SELECT DATENAME(month,ReportDate)+'-'+DATENAME(year,ReportDate)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY DATEPART(year,ReportDate), DATEPART(month,ReportDate), DATENAME(month,ReportDate),DATENAME(year,ReportDate)
ORDER BY DATEPART(year,ReportDate), DATEPART(month,ReportDate)
2 голосов
/ 30 апреля 2011

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

SELECT
  SUBSTRING(CONVERT(varchar, ReportDate, 100), 1, 3) + '-' +
  SUBSTRING(CONVERT(varchar, ReportDate, 100), 8, 4)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY
  SUBSTRING(CONVERT(varchar, ReportDate, 100), 1, 3),
  SUBSTRING(CONVERT(varchar, ReportDate, 100), 8, 4)
ORDER BY MIN(ReportDate)

Кроме того, хотя способ представления выходных данных в формате mmm-yyyy в целом приемлем, я, вероятно, сделал бы то же самое немного иначе. Здесь:

SELECT
  LEFT(DATENAME(month, ReportDate), 3) + '-' +
  DATENAME(year,  ReportDate)
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY
  DATENAME(month, ReportDate),
  DATENAME(year,  ReportDate)
ORDER BY MIN(ReportDate)
2 голосов
/ 30 апреля 2011

Вы можете использовать GROUP BY вместо DISTINCT следующим образом

SELECT SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
        SUBSTRING (convert(varchar, ReportDate, 100),8,4 ) 
FROM [EnvelopsDB].[dbo].[Envelopes]
GROUP BY SUBSTRING (convert(varchar, ReportDate, 100),1,3) +'-'+
          SUBSTRING (convert(varchar, ReportDate, 100),8,4 ) 

При заказе в ReportDate desc, используя row_number () вместо группировки по.

select substring(convert(varchar, Env.ReportDate, 100),1,3) +'-'+
          substring(convert(varchar, Env.ReportDate, 100),8,4 )
from (select
        ReportDate,
        row_number() over(partition by datepart(year, ReportDate), datepart(month, ReportDate)
                          order by (select 1)) as rn
      from [EnvelopsDB].[dbo].[Envelopes]) as Env    
where Env.rn = 1
order by Env.ReportDate desc
1 голос
/ 30 апреля 2011

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

SELECT DISTINCT
    REPLACE(RIGHT(CONVERT(VARCHAR(11), ReportDate, 106), 8), ' ', '-') AS [Mon-YYYY],
    RANK() OVER(ORDER BY CONVERT(VARCHAR(7), ReportDate, 120) /* [YYYY-MM]*/ DESC) AS r_order
FROM [EnvelopsDB].[dbo].[Envelopes]
ORDER BY r_order DESC
Если вы не хотите указывать псевдоним столбца для MMM-YYYY (который затем можно использовать в ORDER BY), не могли бы вы просто сделать ** ORDER BY 1 DESC **? ВЫБЕРИТЕ DISTINCT SUBSTRING (convert (varchar, ReportDate, 100), 1,3) + '-' + SUBSTRING (конвертировать (varchar, ReportDate, 100), 8,4) ОТ [EnvelopsDB]. [Dbo]. [Конверты] ЗАКАЗАТЬ НА 1 DESC Или просто добавьте псевдоним столбца: ВЫБЕРИТЕ DISTINCT SUBSTRING (convert (varchar, ReportDate, 100), 1,3) + '-' + SUBSTRING (convert (varchar, ReportDate, 100), 8,4) AS ReportDate ОТ [EnvelopsDB]. [Dbo]. [Конверты] ORDER BY ReportDate DESC
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...