MSSQL按日期排序

时间:2015-12-29 18:05:50

标签: sql sql-server tsql sql-order-by

我在下面有这个查询段,我正在尝试从此表中的日期字段构建一个“月 - 年”字符串。从当月开始12个月开始,它的顺序是正确的。

DECLARE @cols AS NVARCHAR(MAX)
SELECT @cols = STUFF(
(SELECT N',' + QUOTENAME(y) AS [text()]
FROM (SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +  
      RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y 
      FROM Products2
     ) AS Y
--ORDER BY y desc
FOR XML PATH('')),
1, 1, N'')

这个查询并没有按照正确的顺序提取日期,我想知道你们是否知道以正确的顺序提取日期的任何巧妙的技巧。我可以引入startDate列并对其进行排序,但它会带来重复项,因为它可能在同一个月有几个条目。我在这里创建了一个示例表http://sqlfiddle.com/#!6/3a500/5

3 个答案:

答案 0 :(得分:2)

您可以使用

DECLARE @cols AS NVARCHAR(MAX);

SELECT @cols = STUFF((SELECT N',' + QUOTENAME(y) AS [text()]
                      FROM   (SELECT CONVERT(CHAR(3), StartDate, 0) + '-'
                                     + RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2) AS y,
                                     MIN(StartDate)                                AS z
                              FROM   Products2
                              GROUP  BY CONVERT(CHAR(3), StartDate, 0) + '-'
                                        + RIGHT(CONVERT(VARCHAR, YEAR(StartDate)), 2)) AS Y
                      ORDER  BY z
                      FOR XML PATH('')), 1, 1, N'');

SELECT @cols; 

SQL Fiddle

答案 1 :(得分:2)

看起来您只是获得月份/年份,因此我们可以截断到该月的第一天并将其包含在查询中。

DATEADD(month, DATEDIFF(month, 0, StartDate), 0)  monthStart

现在我们可以通过它订购:

DECLARE @cols AS NVARCHAR(MAX);


 SELECT @cols = STUFF(
  (SELECT N',' + QUOTENAME(y) AS [text()]
  FROM (
        SELECT DISTINCT CONVERT(char(3), StartDate, 0) + '-' +  
        RIGHT(CONVERT(varchar, YEAR(StartDate)), 2) AS y, 
        DATEADD(month, DATEDIFF(month, 0, StartDate), 0)  monthStart
        FROM Products2
       ) AS Y
  ORDER BY monthStart
  FOR XML PATH('')),
1, 1, N'');

select @cols;

这是输出:

  

[减速-15],[一月16],[FEB-16],[MAR-16],[APR-16],[五月-16],[6月-16],[07月16] [8 - 16],[九月16],[OCT-16],[NOV-16],[十二月-16]

这是你在找什么?这是一个小提琴: http://sqlfiddle.com/#!6/3a500/67

更好的是,只需选择不同的月份开始日期,然后只对其进行字符串转换。

   DECLARE @cols AS NVARCHAR(MAX);

     SELECT @cols = STUFF(
      (SELECT N',' + QUOTENAME(CONVERT(char(3), monthStart, 0) + '-' +  
            RIGHT(CONVERT(varchar, YEAR(monthStart)), 2)) AS [text()]
      FROM (
            SELECT DISTINCT 
                DATEADD(month, DATEDIFF(month, 0, StartDate), 0)  monthStart
      FROM Products2
           ) AS Y
      ORDER BY monthStart
      FOR XML PATH('')),
    1, 1, N'');

    select @cols;

这是小提琴: http://sqlfiddle.com/#!6/3a500/72

答案 2 :(得分:1)

如果您使用的是SQL Server 2012+,则可以使用FORMAT功能:

DECLARE @cols AS NVARCHAR(MAX);

;WITH cte AS       -- get only one date per month/year
(
  SELECT MIN(StartDate) AS StartDate
  FROM #Products2 
  GROUP BY YEAR(StartDate),MONTH(StartDate)
)
SELECT @cols = STUFF((SELECT  ',' + QUOTENAME(FORMAT(StartDate, 'MMM-yy'))
                      FROM cte
                      ORDER BY StartDate      
                      FOR XML PATH('')),
                    1, 1, N'');

SELECT @cols;

LiveDemo

输出:

╔══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║                                                        result                                                        ║
╠══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ [Dec-15],[Jan-16],[Feb-16],[Mar-16],[Apr-16],[May-16],[Jun-16],[Jul-16],[Aug-16],[Sep-16],[Oct-16],[Nov-16],[Dec-16] ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝