2016-08-30 7 views
3

私の知る限り、最新の請求書日付とその請求書日付の年と月の組み合わせを取得しようとするSQLビューがあります。これらの値は、その月の数量を数えるために使用されます。誰かのコードでのSQLの変換(日付+年(日付))

マイSQLの知識が基本であると私は、なぜ人はこの部分を行うだろうかわからない:

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

コードの残りの部分などTOP(100)PERCENT部を含む、私はかなりしていますに満足。

問題のパーツがロジックミスであるかどうか、また場合によってはMax Invoice Dateとは異なる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 
+2

なぜ誰かが最大のMM/YYYYを望むのかわかりません。それは正しく見えませんが、おそらくいくつかの不可解な理由があります。 –

+0

'InvoiceDate'が実際の' date'または 'datetime'または' datetime2'型の場合、 'CONVERT'の代わりに' DATEPART' sql関数を使うことができます。それを文字列に変換する行為は、ビューのコンシューマーの便宜のためのものかもしれませんが、なぜそれが正しいかを見るためには、そのコードを参照する必要があります。 – Igor

+0

ビューからORDER BYを取り除いてください。それは役に立たないだけでなく、実際にパフォーマンスを傷つける可能性があります。注文は、SQL Serverで実際に行う必要がある場合は、一番外側のクエリの一部にする必要があります。 – dean

答えて

1

面白いですが、理にかなっています。文字列 "12"は任意の月の定式化でMAX文字列になり、そのレコードは前年になります。これは2013年の8月に実際の最大値が発生した場合にも意味があります。 、オリジナルのプログラマが前半に日付要素を使用しなかった理由として

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 

そのかなり滑らかな、あなたは "を取得する:あなたが最初の列にある同じ日付に変換されるように変換内側MAX MM/DD/YYYYの最初の3文字を取得することで、/ '文字を無料で使用できます。私が考えていたものではありませんが、実際にはコマンドや文字列の連結を保存します。

+0

それは、それが滑らかなアプローチでエラーがあることを示唆していますか?私の例でYearMonthのあなたの出力は08/2013 ...私が期待しているもの。 – Jak

+0

@Jak:はい。その1つの部分は滑らかだった、私は実際にLukStormsがそれをより良く下回った方法を好む。私は思っていないことをする方法を尊重しようとします。 MM/DD/YYYYの最初の3文字を取得すると、MM/YYYYが滑らかになります。それをDD/MM/YYYYでフォーマットし、最後の7文字を取得することも滑らかです! –

+0

あなたは完全に正しいとわかりました。問題の人を納得させる助けになりました。ありがとうございました。 – Jak

0

以下のクエリは、最大日付を形式に変換します。 最初に各日付の日付部分を変換し、次に計算されたvarcharsの最大値を取得するという間違った考え方とは異なります。

「YearMonth」という名前の計算列では、年と月で始まる値が予想されます。

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; 

(これは、YYYY/MM形式をソートすることも簡単です)与える:

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 
関連する問題