2017-02-10 21 views
1

私はピボットテーブルの2つの異なる一時テーブルの間の日付のフルレンジを取得したいと思います。クエリは次のようになります:注文番号のXMLパス

DECLARE @cols AS NVARCHAR(MAX) 
DECLARE @colswithNoNulls AS NVARCHAR(MAX) 
DECLARE @query AS NVARCHAR(MAX) 
DECLARE @tanggal_awal DATE 
DECLARE @tanggal_akhir DATE 
DECLARE @print NVARCHAR(MAX) 
DECLARE @querycount AS NVARCHAR(MAX) 

CREATE TABLE #datatable 
(
    product_id int, 
    product_date date, 
    product_ammount int 
) 

SET @tanggal_awal = convert(DATE,'02-01-2017') 
SET @tanggal_akhir = convert(DATE,DATEADD(dd,-1,(DATEADD(mm,1,@tanggal_awal)))) 

INSERT INTO #datatable (product_id,product_date,product_ammount) 
VALUES (1, GETDATE(), 100), (1, GETDATE(), 900), 
     (2, DATEADD(DD, -1, GETDATE()), 400), 
     (3, DATEADD(DD, 4, GETDATE()), 300), 
     (1, DATEADD(DD, 4, GETDATE()), 200), 
     (2, DATEADD(DD, 2, GETDATE()), 700), 
     (4, DATEADD(DD, -3, GETDATE()), 1000), 
     (4, DATEADD(MM, 1, GETDATE()), 200) 

;WITH CTE (datelist,maxdate) AS 
(
    SELECT 
     CONVERT(INT, (MIN(DATEPART(day, @tanggal_awal)))) datelist, 
     CONVERT(INT, MAX(DATEPART(day, product_date))) maxdate 
    FROM 
     #datatable 

    UNION ALL 

    SELECT 
     CONVERT(INT, (DATEPART(day, datelist))), 
     CONVERT(INT, (DATEPART(day, @tanggal_akhir))) 
    FROM 
     cte 
    WHERE 
     datelist < maxdate 
) 
SELECT c.datelist 
INTO #temp 
FROM cte c 
ORDER BY c.datelist 
OPTION (maxrecursion 0) 

SELECT * FROM #temp 

SELECT 
    @cols = STUFF((SELECT DISTINCT ',' + QUOTENAME(CONVERT(int, datelist)) 
        FROM #temp 
        FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '') 

PRINT @cols 

しかし、結果は私が期待しているようではありません。印刷結果に基づいて、それはこのようなものを示しています

[1],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[2],[20],[21],[22],[23],[24],[25],[26],[27],[28],[3],[4],[5],[6],[7],[8],[9] 

私が望む結果は、この

[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28] 

私はこのクエリを解決するために何をすべきようなもの?ありがとうございました:)

答えて

2

DISTINCTキーワードを削除し、SELECTステートメントにORDER BY句を追加します。ここでは

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(CONVERT(int, datelist)) 
       FROM #temp 
       ORDER BY CONVERT(int, datelist) 
       FOR XML PATH(''), TYPE 
       ).value('.', 'NVARCHAR(MAX)') 
       ,1,1,'' 
       ) 
+0

これは、等しい2つの数字を生成する可能性があります。これが私の答え(それはあなたとほとんど同じです)に私がgroup by節を追加した理由です。 –

+0

だから私はなぜこの問題で別物を使うべきではないのですか?あなたの答えは魅力のように働く:)。私たちがxml parhで別れたときにメカニックを私に説明できますか? –

+0

この場合、SQL Serverは 'DISTINCT 'を許可しません。試してみると、SELECT DISTINCTが指定されていると、_ORDER BY項目が選択リストに表示される必要があります。エラーメッセージ。 'datelist'の項目が繰り返されないことを保証する必要があります。 @FarisFajarで提案されているように 'GROUP BY'を追加するか、'#temp'テーブルにデータを入れるときに 'DISTINCT'を使います:' SELECT DISTINCT c.datelist INTO#temp' – Serge

1

はそれを行うための一つの方法である:

SELECT @cols = STUFF((SELECT ',' + QUOTENAME(CONVERT(int, datelist)) 
       FROM #temp 
       GROUP BY datelist 
       ORDER BY CONVERT(int, datelist) 
       FOR XML PATH(''), TYPE 
       ).value('.', 'NVARCHAR(MAX)') 
       ,1,1,'' 
       ) 

私が変更しましたDISTINCTGROUP BYとなり、ORDER BY句にCONVERT(int, datelist)を使用できるようになりました。

1
Getting TheOutput as 
    [1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28] 

     Begin TRAN 

     DECLARE @cols AS NVARCHAR(MAX) 
     DECLARE @colswithNoNulls AS NVARCHAR(MAX) 
     DECLARE @query AS NVARCHAR(MAX) 
     DECLARE @tanggal_awal DATE 
     DECLARE @tanggal_akhir DATE 
     DECLARE @print NVARCHAR(MAX) 
     DECLARE @querycount AS NVARCHAR(MAX) 

     CREATE TABLE #datatable 
     (
      product_id int, 
      product_date date, 
      product_ammount int 
     ) 

     SET @tanggal_awal = convert(DATE,'02-01-2017') 
     SET @tanggal_akhir = convert(DATE,DATEADD(dd,-1,(DATEADD(mm,1,@tanggal_awal)))) 

     INSERT INTO #datatable (product_id,product_date,product_ammount) VALUES 
        (1,GETDATE(),100), 
        (1,GETDATE(),900), 
        (2,DATEADD(DD,-1,GETDATE()),400), 
        (3,DATEADD(DD,4,GETDATE()),300), 
        (1,DATEADD(DD,4,GETDATE()),200), 
        (2,DATEADD(DD,2,GETDATE()),700), 
        (4,DATEADD(DD,-3,GETDATE()),1000), 
        (4,DATEADD(MM,1,GETDATE()),200) 

     ;WITH CTE (datelist,maxdate) AS 
     (
      SELECT CONVERT(INT,(MIN(DATEPART(day,@tanggal_awal)))) datelist, CONVERT(INT,MAX(DATEPART(day,product_date))) maxdate 
      FROM #datatable 
      UNION ALL 
      SELECT CONVERT(INT,(DATEPART(day,datelist))), CONVERT(INT,(DATEPART(day,@tanggal_akhir))) 
      FROM cte 
      WHERE datelist < maxdate 
     ) SELECT c.datelist 
      INTO #temp 
      FROM cte c 
      ORDER BY c.datelist 
      OPTION (maxrecursion 0) 

     --select * from #temp 

     SELECT @cols = STUFF((SELECT ',' + QUOTENAME(CONVERT(nvarchar(20), datelist)) 
         FROM #temp t1 
         FOR XML PATH ('')) 
        , 1, 1, '') from #temp t2 


     SELECT @cols   


     PRINT @cols 

     ROLLBACK TRAN 
+0

あなたの答えは魅力的です。 –

+0

@FarisFajarようこそ –

関連する問題