0

クエリで使用するCommon Table Expression (CTE)inを構築しています。SQL Server 2008PIVOT

途中で文字列データを挟む数値があるため、出力を適切にソートするのに苦労しています。これを行うことは可能ですか?

これは簡単で汚い例です。実際のクエリは、数年分の値にまたがります。

例:

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]

編集

もちろん、質問を投稿した後、私の脳は働き始めました。1日ではなく1週間を追加するように変更してから、選択で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
4

6 に答える 6

1

サンプル SQL コードが表示されません (そのサイトはブラックリストに登録されています)。

そのデータを適切な順序でソートするための秘訣は、最初に長さを使用してから値を使用することです。

select col
from t
order by left(col, 6), len(col), col;
于 2013-05-29T21:46:13.217 に答える
1

「order by year」を使用して、2 つの一時的な列 (スペースを節約するために smallint の年と tinyint の週 … またはスペースが問題にならず、高速実行を希望する場合は datepart 整数を直接使用する) でソートすることを検討しましたか? 、 週" ?

より適切なタイプ(私が提案するもの)を使用して日付を保存すると、次のようになります。

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

また、文字列操作はクエリを遅くすることに注意してください。可能な場合は避けてください。

于 2013-05-29T21:51:59.280 に答える
0

列の開始部分と終了部分を整数に変換する別のオプションを次に示します。

SELECT *
FROM YourTable
ORDER BY CAST(SUBSTRING(yourcolumn,1,4) as int), 
  CAST(SUBSTRING(yourcolumn,CHARINDEX('Week',yourcolumn)+4,len(yourcolumn)) as int)

これは、データの形式が常に同じであると仮定して機能します。

于 2013-05-29T21:52:37.160 に答える
0

私はゴードンの答えが好きですが、あなたがあなたの注文でテキスト操作に夢中になっているなら:

ORDER BY     CAST(REPLACE(LEFT('[2012-Week48]',5),'[','')AS INT)
            ,CAST(REPLACE(RIGHT('[2012-Week48]',CHARINDEX('Week','[2012-Week48]')-4),']','') AS INT)
于 2013-05-29T21:50:17.360 に答える
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
于 2013-05-30T04:31:24.990 に答える