T-SQL。 GroupBy截断了DATETIME并按以下顺序排序

时间:2019-03-23 20:07:39

标签: sql sql-server tsql

我有一个简单的订单表,例如:

Order
=========
Date (DATETIME)
Price (INT) 

我想知道我们每个月的收入和产出应为:

January-2018 : 100 
February-2018: 200
...
January-2019: 300
...

我有以下SQL:

SELECT 
    DATENAME(MONTH , DATEADD(M, t.MDate , -1 ) ) + '-' + CAST(t.YDate as NVARCHAR(20)),
    SUM(Price)
FROM 
(
SELECT 
    DATEPART(YYYY, o.Date) as YDate,
    DATEPART(MM, o.Date) as MDate,  
    Price
FROM [Order] o
) t
GROUP BY t.YDate, t.MDate
ORDER BY t.YDate, t.MDate

可以吗?或者有更好的方法吗?

3 个答案:

答案 0 :(得分:0)

也许只是这个?

with Orders as (
  select convert(date,'2018-01-15') as [date], 10 as Price union all
  select convert(date,'2018-01-20'), 20 union all
  select convert(date,'2018-01-30'), 30 union all
  select convert(date,'2018-02-15'), 20 union all
  select convert(date,'2018-03-15'), 40 union all
  select convert(date,'2018-03-20'), 50

)
select 
  datename(month,o.Date) + '-' + datename(year,o.Date) + ': ' + 
  convert(varchar(max),SUM(Price))
FROM [Orders] o
group by datename(month,o.Date) + '-' + datename(year,o.Date)
order by 1 desc

我不太满意,为什么要删除查询中的一个月,我没有这样做。您可以在这里进行测试:https://rextester.com/GRKK80105

答案 1 :(得分:0)

如果您使用的是Sql Server 2012或+,则还可以使用format函数。

select cast('2018-02-23 15:34:09.390' as datetime)  as datenew, 100 as price  into #temp union all 
select cast('2018-02-24 15:34:09.390' as datetime)  as datenew, 300 as price   union all 
select cast('2018-03-10 15:34:09.390' as datetime)  as datenew, 500 as price   union all 
select cast('2018-03-11 15:34:09.390' as datetime)  as datenew, 700 as price   union all 
select cast('2019-02-23 15:34:09.390' as datetime)  as datenew, 900 as price   union all 
select cast('2019-02-23 15:34:09.390' as datetime)  as datenew,  1500 as price    

select Monthyear,  total  from  ( 
select format(datenew, 'MMMM-yyyy') Monthyear, format(datenew, 'yyyyMM')  NumMMYY ,sum(price) total from #temp 
group by format(datenew, 'MMMM-yyyy') , format(datenew, 'yyyyMM') ) test 
order by NumMMYY

由于格式会将其转换为nvarchar,因此我不得不在子查询中再创建一列以对其进行正确排序。如果您不介意再增加一列,则不必使用子查询,也可以将其与另一列一起排序。我找不到其他方法(除了case语句不是一个好主意)可以在同一选择中完成

Output: 
 Monthyear      Total
 February-2018  400
 March-2018     1200
 February-2019  2400

答案 2 :(得分:0)

format()是必经之路。我建议:

select format(o.date, 'MMMM-yyyy') as Monthyear,    
       sum(o.price) as total 
from orders o
group by format(datenew, 'MMMM-yyyy')
order by min(o.date)