2016-11-22 115 views
0

我有一個表,其中某些日期放置了一定數量的條目。下面是表結構:在SQL Server中按月份名稱自定義排序

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至4月2016年從2015年10至9月2016年同樣,如果用戶選擇2015年10月,結果將顯示

我該如何處理ORDER BY條款中的條件?

+1

你不會......你還需要一個where子句'如果DateofEntry日期之間,並且每年以通過DateofEntry Asc' dateprovided + 1,因爲它似乎像你只需要1年的記錄....使用之間。 – xQbert

+0

@xQbert這隻會刪除邊界外的記錄。這不是我的問題。我可以輕鬆做到這一點。它關於之後的分類。 –

+0

爲什麼不按年排列(E.DateofEntry)asc,Month(E.DateofEntry)Asc'工作? – xQbert

回答

0

所有的答案和建議,我也碰到過這裏,我覺得這種方式(在問題的意見通過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 

提琴證明這樣的:http://rextester.com/CJFFP5640

起初,我使用下面的查詢:

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 

下面就來證明這一點的小提琴:http://rextester.com/LEVD30653

說明(TL非; DR)

你可以看到,它本質上是相同的WHERE條款。但是,頂部的查詢使用更簡單的邏輯進行排序,並且更流暢,更易讀。

請注意第二個解決方案(使用CASE聲明)根據用戶提供的月份編號對月份編號進行排序,即如果用戶提供2015年12月份,則第二個解決方案將2015年12月編號爲1,2016年1月爲2,2016年2月3等等等等。如果你想在這些數據的基礎上工作,這可能會更有益處。

就我的用例而言,這樣做更有意義。但是,就問題的範圍而言,頂部的查詢是最好的。

2

您可以使用模算術將偏移量放入ORDER BY。對於4月:

ORDER BY (MONTH(e.DateOfEntry) + 12 - 4) % 12 
--------------------------------------^ month number to start with 

(該+ 12簡直是讓我沒有記住,如果%返回負數負的操作數)。

如果你想要的結果按時間順序,可以改爲做:

ORDER BY MIN(e.DateOfEntry) 
0

假設你的參數是一個整數稱爲@FirstMonth,你可以用得到正確的順序月:

案例

WHEN MONTH(e.DateOfEntry) < @FirstMonth then MONTH(e.DateOfEntry) + 12 

    ELSE MONTH(e.DateOfEntry) 

END AS MonthNumber 
1

如果我正確

瞭解你「這意味着,如果用戶選擇的2015年5月的結果應進行排序,從2015年5至4月2016年同樣,如果用戶選擇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(@[email protected]+'01' AS DATE) 
GROUP BY MONTH(e.DateOfEntry), DateName(MONTH,e.DateOfEntry) 
ORDER BY MONTH(e.DateOfEntry) ASC 

結果:

enter image description here

+0

但是,非常接近,1月份,2月份等月份沒有結果。說了這樣的話,你的想法是在正確的方向。 :) –

+0

@SatwikNadkarny很抱歉,這是一個愚蠢的錯誤。查看更新的答案 –

1

您可以按照以下順序使用百靈:

ORDER BY YEAR(e.DATEOFENTRY),  
    DATEPART(MM,e.DAREOFENTRY) 

這將按照年份和月份的下一個排序結果。

這裏您需要在Select中指定這些相同的列。

0

添加一個WHERE子句查詢

WHERE MONTH(e.DateOfEntry) < User.Month AND YEAR(e.DateOfEntry) < User.Year AND MONTH(e.DateOfEntry) > (User.Month-1) AND YEAR(e.DateOfEntry) > (User.Year+1)