0

PIVOT 쿼리에 사용할 Common Table Expression (CTE)SQL Server 2008에 구축하고 있습니다.양쪽 끝에 varchar 문자열을 숫자 값으로 올바르게 정렬하는 방법은 무엇입니까?

중간에 문자열 데이터를 샌드위치하는 숫자 값이 있기 때문에 출력을 올바르게 정렬하는 데 어려움이 있습니다. 이것을 할 수 있습니까?

이 예는 빠르고 간단한 예이며 실제 검색어는 몇 년 동안 가치가 있습니다.

예 :

Declare @startdate as varchar(max); 
Declare @enddate as varchar(max); 
Set @startdate = cast((DATEPART(yyyy, GetDate())-1) as varchar(4))+'-12-01'; 
Set @enddate = cast((DATEPART(yyyy, GetDate())) as varchar(4))+'-03-15'; 

WITH DateRange(dt) AS 
    (
     SELECT CONVERT(datetime, @startdate) dt 
     UNION ALL 
     SELECT DATEADD(dd,1,dt) dt FROM DateRange WHERE dt < CONVERT(datetime, @enddate) 
    ) 
    SELECT DISTINCT ',' + QUOTENAME((cast(DATEPART(yyyy, dt) as varchar(4)))+'-Week'+(cast(DATEPART(ww, dt) as varchar(2)))) FROM DateRange 

전류 출력 :

,[2012-Week48] 
,[2012-Week49] 
,[2012-Week50] 
,[2012-Week51] 
,[2012-Week52] 
,[2012-Week53] 
,[2013-Week1] 
,[2013-Week10] 
,[2013-Week11] 
,[2013-Week2] 
,[2013-Week3] 
,[2013-Week4] 
,[2013-Week5] 
,[2013-Week6] 
,[2013-Week7] 
,[2013-Week8] 
,[2013-Week9] 

원하는 출력 :

,[2012-Week48] 
,[2012-Week49] 
,[2012-Week50] 
,[2012-Week51] 
,[2012-Week52] 
,[2012-Week53] 
,[2013-Week1] 
,[2013-Week2] 
,[2013-Week3] 
,[2013-Week4] 
,[2013-Week5] 
,[2013-Week6] 
,[2013-Week7] 
,[2013-Week8] 
,[2013-Week9] 
,[2013-Week10] 
,[2013-Week11] 

EDIT 물론

질문을 게시 한 후 두뇌가 작동하기 시작했습니다. DATEADD을 1 일 대신 1 주 추가 한 다음, DISTINCT을 선택하여 꺼냈다.

DECLARE @startdate AS VARCHAR(MAX); 
DECLARE @enddate AS VARCHAR(MAX); 
SET @startdate = CAST((DATEPART(yyyy, GetDate())-1) AS VARCHAR(4))+'-12-01'; 
SET @enddate = CAST((DATEPART(yyyy, GetDate())) AS VARCHAR(4))+'-03-15'; 

WITH DateRange(dt) AS 
    (
      SELECT CONVERT(datetime, @startdate) dt 
      UNION ALL 
      SELECT DATEADD(ww,1,dt) dt FROM DateRange WHERE dt < CONVERT(datetime, @enddate) 
    ) 
    SELECT ',' + QUOTENAME((CAST(DATEPART(yyyy, dt) AS VARCHAR(4)))+'-Week'+(CAST(DATEPART(ww, dt) AS VARCHAR(2)))) FROM DateRange 
+1

나쁜 접근 방법처럼 보입니다. 문자열로 시작하여 datetimes에 캐스팅하고 쿼리를 실행 한 다음 다시 문자열로 변환합니다. 왜 datetimes로 시작하고, 쿼리를 실행하고, 형식화 된 날짜를 출력하지 않고 실제 날짜로 정렬합니까? –

+0

피벗 테이블 Im은 실제 날짜를 저장하지만 수정 된 율리우스 형식으로 저장하기 때문에. 필자는 지난 수개월에 걸친 요일별로 피벗을 만들어야합니다. 이것은 전반적인 솔루션의 첫 번째 분기 일 뿐이지 만 필자가 필요로하는 것입니다. 이것에 관해서는 지나치게 성능에 관심이없는 Im은 한 달에 한 번 실행되어 합리적인 시간 내에 완료됩니다. 더 나은 방법이있을 수 있습니다. 그러나 이것이 제가 지금 해결책으로 가지고있는 것입니다. – ProfessionalAmateur

답변

0

내가 쿼리의 DATEADD 부분을 변경하고 DISTINCT을 제거 할 필요가 있었다. 변경되면 주문이 올바르게 정렬 됨

DECLARE @startdate AS VARCHAR(MAX); 
DECLARE @enddate AS VARCHAR(MAX); 
SET @startdate = CAST((DATEPART(yyyy, GetDate())-1) AS VARCHAR(4))+'-12-01'; 
SET @enddate = CAST((DATEPART(yyyy, GetDate())) AS VARCHAR(4))+'-03-15'; 

WITH DateRange(dt) AS 
    (
      SELECT CONVERT(datetime, @startdate) dt 
      UNION ALL 
      SELECT DATEADD(ww,1,dt) dt FROM DateRange WHERE dt < CONVERT(datetime, @enddate) 
    ) 
    SELECT ',' + QUOTENAME((CAST(DATEPART(yyyy, dt) AS VARCHAR(4)))+'-Week'+(CAST(DATEPART(ww, dt) AS VARCHAR(2)))) FROM DateRange 
1

나는 (내가있는 곳에서 블랙리스트에 올라있는) 샘플 SQL 코드를 볼 수 없다. 여기

는 적절한 순서로 데이터를 정렬하는 트릭이 값을 먼저하고 길이를 사용하는 것입니다 : 나는 고든의 답변을 좋아

select col 
from t 
order by left(col, 6), len(col), col; 
+0

이 방법의 문제점은 년이 다를 수 있지만 길이가 같을 수 있다는 것입니다. 나는 개념을 좋아한다. – sgeddes

+0

@sgeddes. . . 이봐. 당신 말이 맞아요. 이것은 원래 1 년에 관계없이 모든 1 주를 함께했습니다. 나는 문자열의 처음 6 문자를 가져 와서 그것을 고쳤습니다. –

0

,하지만 당신은에 열중 텍스트 조작에 있다면 주문에 의해 :

ORDER BY  CAST(REPLACE(LEFT('[2012-Week48]',5),'[','')AS INT) 
      ,CAST(REPLACE(RIGHT('[2012-Week48]',CHARINDEX('Week','[2012-Week48]')-4),']','') AS INT) 
1

당신은 공간이 당신에게 문제가 아닌 경우 날짜 부분의 정수를 사용하여 직접 공간을 절약 ...하거나 TINYINT에서 SMALLINT 및 주에 두 일시적으로 열 (년에 정렬 생각하고 당신은 빠른 것을 선호 실행)와 함께 "년, 주"순서를 사용합니까?

좀 더 적합한 유형 (I 제안 것)를 사용하여 날짜를 저장하는 경우, 그 다음이 될 것입니다 :

또한
WITH [Define the CTE expression name and column list] 
AS 
    (
    SELECT CAST(DATEPART(yyyy, dt) as smallint(4)) year, cast(DATEPART(ww, dt) as tinyint(2)) week, [your columns here] 
    FROM DateRange WHERE dt < @enddate 
) 
[Define the outer query referencing the CTE name] 
ORDER BY year, week; 
GO 

, 가능하면 그래서 그들을 피하기 쿼리 속도가 느려집니다 해당 문자열 작업을 유의하시기 바랍니다!

0

다음은 열의 시작 부분과 끝 부분을 정수로 변환하는 또 다른 옵션입니다.

이 데이터의 형식을 가정 작동합니다

SELECT * 
FROM YourTable 
ORDER BY CAST(SUBSTRING(yourcolumn,1,4) as int), 
    CAST(SUBSTRING(yourcolumn,CHARINDEX('Week',yourcolumn)+4,len(yourcolumn)) as int) 
은 항상 동일합니다.당신이 문자열을 생성하는 dt을 사용하고 있기 때문에

0

, 당신은 날짜의 부품을 사용하여 분류한다 :

WITH DateRange(dt) ... 
SELECT DISTINCT ',' + QUOTENAM... 
ORDER BY DATEPART(yyyy, dt), DATEPART(ww, dt) 
+0

SELECT에서 yyyy와 ww를 선택하지 않았으므로 DISTINCT가 포함되어있어 그럴 필요가 없습니다. 나는 그것을 고쳤다, 위에 게시했다. – ProfessionalAmateur