SQL Server:按降序选择不同的mon-yyyy格式输出排序

时间:2011-04-30 04:22:00

标签: sql sql-server-2008

我在表格中有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

错误:

  

Msg 145,Level 15,State 1,Line 2
  如果SELECT DISTINCT为,则ORDER BY项必须出现在选择列表中   指定。

获得我需要的输出的最佳SQL查询是什么?

4 个答案:

答案 0 :(得分:5)

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)

答案 1 :(得分:2)

你可以像这样使用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()而不是group by。

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

答案 2 :(得分:2)

我认为最近这里有一个类似的问题,我现在找不到,但答案是这样的:

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)

答案 3 :(得分:1)

如果你不介意结果集中的额外列,那么这将有效。

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(转换(varchar,ReportDate,100),1,3)+' - '+       SUBSTRING(转换(varchar,ReportDate,100),8,4)     FROM [EnvelopsDB]。[dbo]。[信封]     订购1 DESC 或者只添加一个列别名:     选择DISTINCT       SUBSTRING(转换(varchar,ReportDate,100),1,3)+' - '+       SUBSTRING(convert(varchar,ReportDate,100),8,4)AS ReportDate     FROM [EnvelopsDB]。[dbo]。[信封]     订单报告日期DESC