有没有办法在表格的单元格内以分类的方式显示月份

时间:2016-02-26 09:39:50

标签: mysql sql-server

我有一张表格,其中包含以下数据:

enter image description here

有没有办法选择月份列,以便月份不按字母顺序显示,而是按逗号分隔的日历月份排序?例如,第二行应该返回APR,MAY,JUN而不是APR,JUN,MAY。

3 个答案:

答案 0 :(得分: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
;

答案 1 :(得分: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     |
+---------+-------------+

答案 2 :(得分:0)

所以我和Andy在一起,你提出的设计肯定有代码味道,你违反了关系数据库中规范化的概念。但作为一种纯粹的编码练习,这就是你如何做到的。 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)-@pos)
 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