Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在SQL Server中按月份名称进行自定义排序_Sql_Sql Server_Sorting_Sql Server 2012 - Fatal编程技术网

在SQL Server中按月份名称进行自定义排序

在SQL Server中按月份名称进行自定义排序,sql,sql-server,sorting,sql-server-2012,Sql,Sql Server,Sorting,Sql Server 2012,我有一个表格,其中一些日期有一定数量的条目。以下是表格结构: 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

我有一个表格,其中一些日期有一定数量的条目。以下是表格结构:

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
中指定日期的条目总数

我正在尝试制定一个查询,其中每个月显示条目的总数。我目前有以下问题:

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
子句中获取此条件?

您可以使用模运算将偏移量放入
ORDER BY
中。四月:

ORDER BY (MONTH(e.DateOfEntry) + 12 - 4) % 12
--------------------------------------^ month number to start with
+12
非常简单,因此我不必记住
%
是否返回带负数操作数的负数。)

如果您希望按时间顺序获得结果,可以改为:

ORDER BY MIN(e.DateOfEntry)

您可以使用模运算将偏移量放入
顺序中。四月:

ORDER BY (MONTH(e.DateOfEntry) + 12 - 4) % 12
--------------------------------------^ month number to start with
+12
非常简单,因此我不必记住
%
是否返回带负数操作数的负数。)

如果您希望按时间顺序获得结果,可以改为:

ORDER BY MIN(e.DateOfEntry)

假设您的参数是一个名为@FirstMonth的整数,您可以使用以下方法获得正确的月份顺序:

案例

当月份(e.DateOfEntry)<@FirstMonth然后月份(e.DateOfEntry)+12
其他月份(如入境日期)
以MonthNumber结束

假设您的参数是一个名为@FirstMonth的整数,您可以使用以下方法获得正确的月份顺序:

案例

当月份(e.DateOfEntry)<@FirstMonth然后月份(e.DateOfEntry)+12
其他月份(如入境日期)
以MonthNumber结束

如果我理解正确

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

这应该起作用:

样本数据:

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')
使用参数进行查询:

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
结果:


如果我没听错的话

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

这应该起作用:

样本数据:

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')
使用参数进行查询:

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
结果:


您可以按顺序使用以下软件

  ORDER BY YEAR(e.DATEOFENTRY),    
  DATEPART(MM,e.DAREOFENTRY)
这将首先对今年的结果进行排序,然后对下个月的结果进行排序


这里您需要在Select中指定这些相同的列。

您可以按以下顺序使用

  ORDER BY YEAR(e.DATEOFENTRY),    
  DATEPART(MM,e.DAREOFENTRY)
这将首先对今年的结果进行排序,然后对下个月的结果进行排序


在这里,您需要在Select中指定这些相同的列。

在我在这里遇到的所有答案和建议中,我发现这种方式(由xQbert在问题注释中建议)是最简单的方式。

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
一把小提琴来证明这一点:

最初,我使用以下查询:

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
选择sortingList.monthof条目,
sortingList.TotalEntries,
sortingList.MonthNumber
从(
选择DateName(月,日期添加(月,月(e.DateOfEntry),0)-1)+''+转换(nvarchar(20),年(e.DateOfEntry))作为MonthOfEntry,
合计(即分录)作为总分录,
案例
当((月(如进入日期)-月(@StartDate))>0时
然后(月(如进入日期)-月(@StartDate))+1
当((月(如进入日期)-月(@StartDate))=0时
那么1
其他的
((12个月(@StartDate))+(月(e.DateOfEntry)))+1
结束
如蒙纳姆
从条目e开始
其中e.DateOfEntry>=@StartDate和e.DateOfEntry
这里有一把小提琴来证明这一点:

解释(非TL;DR)

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

请注意,第二个解决方案(使用
案例
语句)根据用户提供的月编号对月编号进行排序,即如果用户提供2015年12月,则第二个解决方案将2015年12月编号为1,2016年1月编号为2,2016年2月编号为3,依此类推。在您希望在这些数据之上工作的情况下,这可能更有益


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

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

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
一把小提琴来证明这一点:

最初,我使用以下查询:

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
选择sortingList.monthof条目,
索丁