2016-08-30 2 views
3

필자는 이해할 수있는 최신 인보이스 날짜와 해당 인보이스 일자의 년과 월 조합을 얻으려고하는 SQL보기를 가지고 있습니다. 그런 다음이 값을 사용하여 해당 월의 수량을 계산합니다.다른 사람의 SQL 코드 (날짜 + 년 (날짜)) 다른 사람의 코드

내 SQL에 대한 지식은 기본이며 사람이이 부분 할 이유를 잘 모르겠어요 :

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

등 TOP (100) PERCENT 부분을 포함하여 코드의 나머지, 나는 꽤 오전 로 행복한.

문제의 부품이 실수로 작성되었거나 일부 인스턴스에서와 같이 일부 SQL 또는 비즈니스 이유가 Max Invoice Date와 완전히 다른 경우 확실하지 않습니다. 아래

전체 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"는 모든 월 공식에서 최대 문자열이 될 것이며 그 레코드는 이전 연도로 이동합니다. 이는 실제 최대 값이 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 

원래 프로그래머가 상반기에 날짜 부분을 사용하지 않은 이유에 관해서는, 그 꽤 빠르, 당신이 얻을를 '/'문자는 MM/DD/YYYY의 처음 세 문자를 가져 와서 무료로 제공합니다. 내가 생각한 것이 아니라 실제로 명령이나 문자열 연결을 저장합니다.

+0

그런 다음 오류가있는 매끄러운 접근 방법을 제안합니까? 내 예제에서 YearMonth에 대한 결과는 08/2013입니다. – Jak

+0

@Jak : 예. 그 한 부분은 매끄러운, 나는 실제로 LukStorms가 더 나은 아래에 그것을했던 방식을 좋아한다. 나는 내가 생각하지 못했던 일을 존중하려고 노력합니다. MM/DD/YYYY의 처음 세 글자를 잡으면 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 형식을 정렬도 쉽게) 다음 HAVING은 WHERE 절을 사용하여 전환 된

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

하는 것으로.
동일하지만 잠재적으로 더 빠른 결과를 제공합니다.

MM/DDDD 형식이 선호되는 경우이 형식으로 계산됩니다.

RIGHT(CONVERT(varchar(10), MAX(InvoiceDate), 103),7) as MonthYear 
관련 문제