SQL:显示" 2017年3月1日"而不是" 2017-03-01"问题与集团

时间:2017-04-14 11:42:53

标签: sql sql-server tsql

我在下面的代码中运行良好,但我想将日期的形状更改为" 2017年3月1日"而不是" 2017-03-01"

SELECT 
    *
FROM 
(   
    SELECT
        [MessageType].[Name],
        CASE WHEN ( Format([OccuredAtUtc], 'yyyy-MM-dd') LIKE '2017-03%' ) THEN Format([OccuredAtUtc], 'yyyy-MM-dd')
             ELSE NULL                                                          
             END AS [Time],
        COUNT(*) AS [Count]
    FROM @Table
    INNER JOIN @Table ON
    GROUP BY Format([OccuredAtUtc], 'yyyy-MM-dd'),
             [MessageType].[Name]
) s
WHERE ( [Time] IS NOT NULL )
ORDER BY [Time] ASC

OUTUPUT:

NAME_______TIME______COUNT____
HTTP    2017-03-01    21
HTTP    2017-03-02    37
HTTP    2017-03-03    42
.
.
HTTP    2017-03-31    29
  • 但如果我在代码中那么之后使用 CONVERT(VARCHAR(11),[OccuredAtUtc],106),则 GROUP <存在问题/ strong> ING所以我不能再将日期计算在内了

如果我尝试使用会发生什么 CONVERT(VARCHAR(11),[OccuredAtUtc],106) IN CODE:

//所有被改变的东西都是...... 2件事

SELECT 
    *
FROM 
(   
    SELECT
        [MessageType].[Name],
        CASE WHEN ( Format([OccuredAtUtc], 'yyyy-MM-dd') LIKE '2017-03%' ) THEN CONVERT(VARCHAR(11), [OccuredAtUtc], 106)     --Format([OccuredAtUtc], 'yyyy-MM-dd')
             ELSE NULL                                                          
             END AS [Time],
        COUNT(*) AS [Count]
    FROM @Table 
    INNER JOIN @Table ON
    GROUP BY [OccuredAtUtc],    --Format([OccuredAtUtc], 'yyyy-MM-dd')
             [MessageType].[Name]
) s
WHERE ( [Time] IS NOT NULL )
ORDER BY [Time] ASC

我获得了这个非分组输出:

HTTP    01 Mar 2017 1
HTTP    01 Mar 2017 1
HTTP    01 Mar 2017 1
HTTP    01 Mar 2017 2
HTTP    01 Mar 2017 1
HTTP    01 Mar 2017 1
.
.
HTTP    02 Mar 2017 1
.
.
HTTP    31 Mar 2017 1

猜猜数据类型存在问题

GROUP BY [OccuredAtUtc] ...(最后5行) ...如果我使用整个&#34; CONVERT(VARCHAR(11)将会跳错误),[OccuredAtUtc],106)&#34;在GROUP BY中也是

这有什么简单的解决方案吗?我只需要格式化的日期输出&#34; 2017年3月1日&#34; ...

  

[OccuredAtUtc]中的原始日期:

2017-03-01 12:16:58.5080000
2017-03-01 18:11:53.3090000
2017-03-01 18:34:18.3090000
2017-03-01 20:42:28.8570000
2017-03-01 21:10:36.7070000
.
.
.

提前谢谢!!!

2 个答案:

答案 0 :(得分:2)

您的查询似乎不必要地复杂化。我认为这样做你想要的:

SELECT [MessageType].[Name],
       CONVERT(VARCHAR(11), [OccuredAtUtc], 106) AS [Time],
       COUNT(*) AS [Count]
FROM @Table t INNER JOIN  -- I assume these table names are not the real name
     @Table t2
     ON . . .
WHERE OccuredAtUtc >= '2017-03-01' AND
      OccuredAtUtc < '2017-04-01'
GROUP BY (CONVERT(VARCHAR(11), [OccuredAtUtc], 106),
         [MessageType].[Name]

注意:

  • 您不需要子查询。
  • FROM条款过于简化;我假设表名不是@table
  • 使用where子句在聚合之前过滤。这比在聚合后过滤更有效。
  • 直接比较日期比使用列上的函数调用更有效(索引可用于过滤行)。

答案 1 :(得分:0)

如果您使用SQL Server 2012+,则可以使用FORMAT函数FORMAT(DateColumn,'dd MMM yyyy')