首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Server中按月份名称进行的自定义排序

Server中按月份名称进行的自定义排序
EN

Stack Overflow用户
提问于 2016-11-22 18:40:59
回答 6查看 2.7K关注 0票数 0

我有一张表,在某些日期里,会放置一定数量的条目。以下是表的结构:

代码语言:javascript
复制
ID  EntryName     Entries   DateOfEntry
1       A           20      2016-01-17
2       B           22      2016-01-29
3       C           23      2016-02-17
4       D           19      2016-02-17
5       E           29      2016-03-17
6       F           30      2016-03-17
7       G           43      2016-04-17
8       H           10      2016-04-17
9       I           5       2016-05-17
10      J           120     2016-05-17
11      K           220     2016-06-17
12      L           210     2016-06-17
13      M           10      2016-07-17
14      N           20      2016-07-17
15      O           15      2016-08-17
16      P           17      2016-08-17
17      Q           19      2016-09-17
18      R           23      2016-09-17
19      S           43      2016-10-17
20      T           56      2016-10-17
21      U           65      2016-11-17
22      V           78      2016-11-17
23      W           12      2016-12-17
24      X           23      2016-12-17
25      Y           43      2016-02-17
26      Z           67      2016-03-17
27      AA          35      2015-01-17
28      AB          23      2015-01-29
29      AC          43      2015-02-17
30      AD          35      2015-02-17
31      AE          45      2015-03-17
32      AF          23      2015-03-17
33      AG          43      2015-04-17
34      AH          19      2015-04-17
35      AI          21      2015-05-17
36      AJ          13      2015-05-17
37      AK          22      2015-06-17
38      AL          45      2015-06-17
39      AM          66      2015-07-17
40      AN          77      2015-07-17
41      AO          89      2015-08-17
42      AP          127     2015-08-17
43      AQ          19      2015-09-17
44      AR          223     2015-09-17
45      AS          143     2015-10-17
46      AT          36      2015-10-17
47      AU          45      2015-11-17
48      AV          28      2015-11-17
49      AW          72      2015-12-17
50      AX          24      2015-12-17
51      AY          46      2015-02-17
52      AZ          62      2015-03-17

EntryName是条目标识符,列Entries有列DateOfEntry中指定的日期的总条目数。

我试图制定一个查询,其中的条目总数显示在一个月的基础上。我现在有一个查询:

代码语言:javascript
复制
SELECT      DateName(MONTH, e.DateOfEntry) AS MonthOfEntry,
            MONTH(e.DateOfEntry) AS MonthNumber,
            SUM(e.Entries) AS TotalEntries
FROM        #entry e
GROUP BY    MONTH(e.DateOfEntry), DateName(MONTH,e.DateOfEntry)
ORDER BY    MONTH(e.DateOfEntry) ASC

就显示结果而言,效果很好。但是,我在这里的问题是,我需要在一个月的基础上对结果进行排序,在这个基础上,起始月份是动态的,即由一个参数(由用户提供)产生。

这意味着如果用户选择2015年5月,结果应该从2015年5月到2016年4月进行排序。同样,如果用户选择2015年10月,结果将显示在2015年10月至2016年9月。

我将如何在ORDER BY子句中获得这个条件?

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2016-11-22 18:56:01

对于我在这里遇到的所有答案和建议,我发现这种方式()( xQbert在问题的评论中提出)是最简单的():

代码语言:javascript
复制
SELECT      DateName(MONTH, e.DateOfEntry) + ' ' + CONVERT(NVARCHAR(100), YEAR(e.DateOfEntry)) AS MonthOfEntry,
            MONTH(e.DateOfEntry) AS MonthNumber,
            SUM(e.Entries) AS TotalEntries
FROM        Entry e
WHERE       e.DateOfEntry BETWEEN @StartDate AND (DATEADD(YEAR, 1, @StartDate))
GROUP BY    MONTH(e.DateOfEntry), DateName(MONTH,e.DateOfEntry), YEAR(e.DateOfEntry)
ORDER BY    YEAR(e.DateOfEntry) ASC, MONTH(e.DateOfEntry) ASC

演示这一点的小提琴:http://rextester.com/CJFFP5640

最初,我使用了以下查询:

代码语言:javascript
复制
SELECT      sortingList.MonthOfEntry,
            sortingList.TotalEntries,
            sortingList.MonthNumber
FROM        (
              SELECT            DateName(MONTH, DATEADD(MONTH, MONTH(e.DateOfEntry), 0) - 1) + ' ' + CONVERT(nvarchar(20),YEAR(e.DateOfEntry)) AS MonthOfEntry,
                                SUM(e.Entries) as TotalEntries,
                                CASE
                                    WHEN    ((MONTH(e.DateOfEntry) - MONTH(@StartDate)) > 0)
                                    THEN    (MONTH(e.DateOfEntry) - MONTH(@StartDate)) + 1
                                    WHEN    ((MONTH(e.DateOfEntry) - MONTH(@StartDate)) = 0)
                                    THEN    1
                                    ELSE 
                                            ((12 - MONTH(@StartDate)) + (MONTH(e.DateOfEntry))) + 1
                                END
                                AS MonthNumber
              FROM              Entry e
              WHERE             e.DateOfEntry >= @StartDate AND e.DateOfEntry < DATEADD(YEAR, 1, @StartDate)
              GROUP BY          DateName(MONTH, DATEADD(MONTH, MONTH(e.DateOfEntry), 0) - 1), YEAR(e.DateOfEntry), MONTH(e.DateOfEntry) - MONTH(@StartDate), MONTH(e.DateOfEntry)
            ) sortingList
ORDER BY    sortingList.MonthNumber ASC

这里有一个Fiddle来演示这个:http://rextester.com/LEVD30653

解释(非TL;DR)

您可以看到它本质上是相同的WHERE子句。但是,顶部的查询使用了更简单的排序逻辑,并且更加流畅和可读性更强。

请注意,第二个解决方案(使用CASE语句)按照用户提供的月份编号排序,即如果用户提供2015年12月,那么第二个解决方案将把2015年12月编号定为1,2016年1月为2,2016年2月为3等等。在您想要处理这些数据的情况下,这可能会更有益处。

就我的用例而言,这更有意义。然而,就问题的范围而言,顶部的查询是最好的。

票数 0
EN

Stack Overflow用户

发布于 2016-11-22 18:46:17

您可以使用模块化算法将偏移量放入ORDER BY中。4月份:

代码语言:javascript
复制
ORDER BY (MONTH(e.DateOfEntry) + 12 - 4) % 12
--------------------------------------^ month number to start with

( + 12很简单,所以我不需要记住%是否返回负数的负数。)

如果您想要按时间顺序计算结果,您可以这样做:

代码语言:javascript
复制
ORDER BY MIN(e.DateOfEntry)
票数 2
EN

Stack Overflow用户

发布于 2016-11-22 18:50:53

如果我对你的理解正确

“这意味着,如果用户选择2015年5月,结果应该从2015年5月到2016年4月排序。同样,如果用户选择2015年10月,结果将显示在2015年10月至2016年9月。”

这应该是可行的:

样本数据:

代码语言:javascript
复制
IF OBJECT_ID('tempdb..#entry') IS NOT NULL
    DROP TABLE #entry;

CREATE TABLE #entry(ID INT ,EntryName  VARCHAR(10)  , Entries  INT ,  DateOfEntry DATE);

INSERT INTO #entry (ID  ,EntryName     ,Entries   ,DateOfEntry)
VALUES
(1 ,'A', 20     ,'2016-01-17'),
(2 ,'B', 22     ,'2016-01-29'),
(3 ,'C', 23     ,'2016-02-17'),
(4 ,'D', 19     ,'2016-02-17'),
(5 ,'E', 29     ,'2016-03-17'),
(6 ,'F', 30     ,'2016-03-17'),
(7 ,'G', 43     ,'2016-04-17'),
(8 ,'H', 10     ,'2016-04-17'),
(9 ,'I', 5      ,'2016-05-17'),
(10,'J', 120    ,'2016-05-17'),
(11,'K', 220    ,'2016-06-17'),
(12,'L', 210    ,'2016-06-17'),
(13,'M', 10     ,'2016-07-17'),
(14,'N', 20     ,'2016-07-17'),
(15,'O', 15     ,'2016-08-17'),
(16,'P', 17     ,'2016-08-17'),
(17,'Q', 19     ,'2016-09-17'),
(18,'R', 23     ,'2016-09-17'),
(19,'S', 43     ,'2016-10-17'),
(20,'T', 56     ,'2016-10-17'),
(21,'U', 65     ,'2016-11-17'),
(22,'V', 78     ,'2016-11-17'),
(23,'W', 12     ,'2016-12-17'),
(24,'X', 23     ,'2016-12-17'),
(25,'Y', 43     ,'2016-02-17'),
(26,'Z', 67     ,'2016-03-17'),
(27,'AA',35     ,'2015-01-17'),
(28,'AB',23     ,'2015-01-29'),
(29,'AC',43     ,'2015-02-17'),
(30,'AD',35     ,'2015-02-17'),
(31,'AE',45     ,'2015-03-17'),
(32,'AF',23     ,'2015-03-17'),
(33,'AG',43     ,'2015-04-17'),
(34,'AH',19     ,'2015-04-17'),
(35,'AI',21     ,'2015-05-17'),
(36,'AJ',13     ,'2015-05-17'),
(37,'AK',22     ,'2015-06-17'),
(38,'AL',45     ,'2015-06-17'),
(39,'AM',66     ,'2015-07-17'),
(40,'AN',77     ,'2015-07-17'),
(41,'AO',89     ,'2015-08-17'),
(42,'AP',127    ,'2015-08-17'),
(43,'AQ',19     ,'2015-09-17'),
(44,'AR',223    ,'2015-09-17'),
(45,'AS',143    ,'2015-10-17'),
(46,'AT',36     ,'2015-10-17'),
(47,'AU',45     ,'2015-11-17'),
(48,'AV',28     ,'2015-11-17'),
(49,'AW',72     ,'2015-12-17'),
(50,'AX',24     ,'2015-12-17'),
(51,'AY',46     ,'2015-02-17'),
(52,'AZ',62     ,'2015-03-17')

查询PARAMS:

代码语言:javascript
复制
DECLARE @Month VARCHAR(2) = '05', @Year VARCHAR(4) = '2015'

SELECT      DateName(MONTH, e.DateOfEntry) AS MonthOfEntry,
            MONTH(e.DateOfEntry) AS MonthNumber,
            SUM(e.Entries) AS TotalEntries
FROM        #entry e
WHERE CAST(e.DateOfEntry AS DATE) >= CAST( @Year+@Month+'01' AS DATE)
GROUP BY    MONTH(e.DateOfEntry), DateName(MONTH,e.DateOfEntry)
ORDER BY    MONTH(e.DateOfEntry) ASC

结果:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40749319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档