2016-02-26 19 views
1

我有一個具有以下數據表:有沒有辦法有一個表格的單元格中的排序方式月份

enter image description here

有沒有辦法在選擇個月列這樣一種方式,即月份不按字母順序顯示,而按照以逗號分隔的日曆月進行排序?例如,第二行應該返回APR,MAY,JUN而不是APR,JUN,MAY。

+5

雖然這可以通過拆分SRING技術上完成,適當地整理,並串聯回來 - 你的情況下,聞起來像壞的數據庫設計。考慮將月份數據存儲爲不是逗號分隔的字符串,而是作爲單獨表中的一對多關係存儲。 –

+2

'mysql'或'sql-server' ?? – Wanderer

回答

1

如果SQL-Server

首先創建一個臨時表,表變量或常規表來存儲每個月的訂單。

我剛創建了一個常規表。

CREATE TABLE tbl_month 
(
    Months VARCHAR(3), [order] INT 
); 
INSERT INTO tbl_month VALUES 
('JAN',1), 
('FEB',2), 
('MAR',3), 
('APR',4), 
('MAY',5), 
('JUN',6), 
('JUL',7), 
('AUG',8), 
('SEP',9), 
('OCT',10), 
('NOV',11), 
('DEC',12); 

然後分裂每個逗號分隔值,並與該月順序上表可變加入它並存儲結果設定爲爲了便於在使用中溫度。

SELECT t1.*, t2.[order] into #temp_table from 
(
    SELECT A.qtr, Split.a.value('.', 'VARCHAR(100)') as Months FROM 
    (
     SELECT qtr, 
     CAST ('<M>' + REPLACE(Months, ',', '</M><M>') + '</M>' AS XML) AS Months 
     FROM my_table_name 
    ) AS A CROSS APPLY Months.nodes ('/M') AS Split(a))t1 
JOIN tbl_month t2 
ON t1.Months = t2.Months 
ORDER BY t1.qtr; 

上面的查詢將創建一個臨時表,如下所示。

+---------+--------+-------+ 
| qtr  | Months | order | 
+---------+--------+-------+ 
| 2015-Q1 | MAR | 3  | 
| 2015-Q1 | JAN | 1  | 
| 2015-Q1 | FEB | 2  | 
| 2015-Q2 | APR | 4  | 
| 2015-Q2 | JUN | 6  | 
| 2015-Q2 | MAY | 5  | 
| 2015-Q3 | SEP | 9  | 
| 2015-Q3 | AUG | 8  | 
| 2015-Q3 | JUL | 7  | 
| 2015-Q4 | OCT | 10 | 
| 2015-Q4 | DEC | 12 | 
+---------+--------+-------+ 

然後拼接的月月爲了讓每一個qtr的順序。

SELECT qtr, 
     STUFF 
     (
     (
      SELECT ',' + Months 
      FROM #temp_table AS t2 
      WHERE t2.qtr = t.qtr 
      ORDER BY [order] 
      FOR XML PATH('') 
     ),1,1,'') as Months 
FROM #temp AS t 
GROUP BY qtr 
ORDER BY qtr; 

結果

+---------+-------------+ 
| qtr  | Months  | 
+---------+-------------+ 
| 2015-Q1 | JAN,FEB,MAR | 
| 2015-Q2 | APR,MAY,JUN | 
| 2015-Q3 | JUL,AUG,SEP | 
| 2015-Q4 | OCT,DEC  | 
+---------+-------------+ 
+0

這對我來說工作得很好。非常感謝你Ullas :) –

0

所以我和安迪一起,你提出的設計肯定有代碼味道,你違背了關係數據庫中規範化的概念。但作爲一個純粹的編碼練習,這是你如何做到的。 1)創建一個分割字符串的udf 2)創建一個查詢,該查詢加入到此udf中,並按您創建的新日期排序。


1)

CREATE FUNCTION dbo.splitstring (@stringToSplit VARCHAR(MAX)) 
RETURNS 
@returnList TABLE ([Name] [nvarchar] (500)) 
AS 
BEGIN 

DECLARE @name NVARCHAR(255) 
DECLARE @pos INT 

WHILE CHARINDEX(',', @stringToSplit) > 0 
BEGIN 
    SELECT @pos = CHARINDEX(',', @stringToSplit) 
    SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1) 

    INSERT INTO @returnList 
    SELECT @name 

    SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)[email protected]) 
END 

INSERT INTO @returnList 
SELECT @stringToSplit 

RETURN 
END 

2)

Select theDate = convert(date, left(qtr, 4) + '-' + st.name + '-01') from [dbo].[Qtrs] q 
cross apply dbo.splitstring (q.months) as st 
order by thedate 
1
select 
    qtr 
    ,replace(
     case when charindex('JAN', Months) > 0 then 'JAN,' else '' end 
     + case when charindex('FEB', Months) > 0 then 'FEB,' else '' end 
     + case when charindex('MAR', Months) > 0 then 'MAR,' else '' end 
     + case when charindex('APR', Months) > 0 then 'APR,' else '' end 
     + case when charindex('MAY', Months) > 0 then 'MAY,' else '' end 
     + case when charindex('JUN', Months) > 0 then 'JUN,' else '' end 
     + case when charindex('JUL', Months) > 0 then 'JUL,' else '' end 
     + case when charindex('AUG', Months) > 0 then 'AUG,' else '' end 
     + case when charindex('SEP', Months) > 0 then 'SEP,' else '' end 
     + case when charindex('OCT', Months) > 0 then 'OCT,' else '' end 
     + case when charindex('NOV', Months) > 0 then 'NOV,' else '' end 
     + case when charindex('DEC', Months) > 0 then 'DEC,' else '' end 
     + case when rtrim(ltrim(Months)) != '' then ',' else '' end 
     ,',,' 
     ,'' 
    ) [Months] 
from 
    your_table 
; 
+0

(在SQL Server中)您還需要刪除最後的',';)。 –

+0

對!更新解決方案 –

+0

我建議你'STUFF(case charindex('JAN',Months)> 0 then',JAN'else''end ...,1,1,'')';)。 –

相關問題