SQL Convert(Date + Year(Date)) 在别人的代码中

SQL Convert(Date + Year(Date)) in Someone Else's Code

我有一个 SQL 视图,据我所知,它试图获取最新的发票日期以及该发票日期的年月组合。然后使用这些值来计算该月的数量。

我的 SQL 知识很基础,我不确定为什么这个人会做这部分:

MAX(CONVERT(varchar(3), InvoiceDate, 101) + CONVERT(varchar(4), 
                  YEAR(InvoiceDate))) AS YearMonth

其余代码,包括 TOP(100) PERCENT 部分等,我还算满意。

我不确定所讨论的部分是否存在逻辑错误,或者它是否有一些 SQL 或业务原因,因为在某些情况下它与最大发票日期完全不同。

完整的 SQL 表达式如下:

SELECT TOP (100) PERCENT    
            MAX(InvoiceDate) AS MaxInvoiceDate, 
            StockCode, Warehouse, 
            MAX(CONVERT(varchar(3), InvoiceDate, 101) + CONVERT(varchar(4), YEAR(InvoiceDate))) AS YearMonth
FROM dbo.ArTrnDetail
GROUP BY StockCode, Warehouse
HAVING (Warehouse = 'CS') OR
      (Warehouse = 'PS') OR
      (Warehouse = 'DS') OR
      (Warehouse = 'JS') OR
      (Warehouse = 'JN')
ORDER BY MaxInvoiceDate DESC

以及可能有问题的输出:

MaxInvoiceDate           | StockCode | Warehouse    | YearMonth
----------------------------------------------------------------
2013-08-21 00:00:00.000  | ACH045    | PS           | 12/2012

这很有趣,但也有道理。字符串“12”将成为任何月份公式中的 MAX 字符串,并且该记录转到前一年,如果实际最大值发生在 2013 年 8 月,这也有意义。修复它的最简单方法是移动转换中的 MAX,因此您转换的是第一列中的相同日期:

SELECT TOP (100) PERCENT    
            MAX(InvoiceDate) AS MaxInvoiceDate, 
            StockCode, Warehouse, 
            CONVERT(varchar(3), MAX(InvoiceDate), 101) + CONVERT(varchar(4), YEAR(MAX(InvoiceDate))) AS YearMonth
FROM dbo.ArTrnDetail
GROUP BY StockCode, Warehouse
HAVING (Warehouse = 'CS') OR
      (Warehouse = 'PS') OR
      (Warehouse = 'DS') OR
      (Warehouse = 'JS') OR
      (Warehouse = 'JN')
ORDER BY MaxInvoiceDate DESC

至于为什么原程序员在前半段没有使用datepart,这很巧妙,你通过MM/DD/YYYY的前3个字符免费获得'/'字符。这不是我想到的,但它实际上为您节省了命令或字符串连接。

下面的查询将最大日期转换为一种格式。 不同于先转换每个日期的日期部分,然后取计算出的varchars的最大值的错误思路

对于名为 'YearMonth' 的计算列,人们会期望值以年份开头,然后是月份。 (排序 YYYY/MM 格式也更容易)

SELECT TOP (100) PERCENT    
    StockCode, Warehouse, 
    MAX(InvoiceDate) AS MaxInvoiceDate, 
    CONVERT(varchar(7), MAX(InvoiceDate), 111) as YearMonth
FROM dbo.ArTrnDetail
WHERE Warehouse in ('CS','PS','DS','JS','JN')
GROUP BY StockCode, Warehouse
ORDER BY MaxInvoiceDate DESC;

给出:

MaxInvoiceDate       StockCode  Warehouse   YearMonth
21.08.2013 00:00:00  ACH045     PS          2013/08

请注意,HAVING 已用 WHERE 子句切换。
这将给出相同但可能更快的结果。

如果首选 MM/DDDD 格式,那么它将以该格式进行计算。

RIGHT(CONVERT(varchar(10), MAX(InvoiceDate), 103),7) as MonthYear