0

昨日の質問と@AaronBertrandからの回答で教えられたことを、同様のタイプの問題に実際に使用しようとしました。Microsoft SQL Server 2008 R2 で使用しています

次のようなデータがあります。

SalesPersonID TransDate   Order     DateTotal
1108          8/2/2013    231.95    7713.8
1108          8/2/2013    5805.15   7713.8
1108          8/2/2013    1676.70   7713.8
1108          8/3/2013    159.95    3635.35
1108          8/3/2013    468.90    3635.35
1108          8/3/2013    1160.85   3635.35
1108          8/3/2013    209.95    3635.35
1108          8/3/2013    1161.85   3635.35
1108          8/3/2013    473.85    3635.35
1108          8/4/2013    149.98    3151.68
1108          8/4/2013    793.95    3151.68
1108          8/4/2013    55.00     3151.68
1108          8/4/2013    198.95    3151.68
1108          8/4/2013    398.00    3151.68
1108          8/4/2013    1255.85   3151.68
1108          8/4/2013    299.95    3151.68
1108          8/9/2013    223.95    1413.8
1108          8/9/2013    59.95     1413.8
1108          8/9/2013    1129.90   1413.8
1108          8/30/2013   1396.43   1396.43
1108          8/31/2013   89.95     1735.65
1108          8/31/2013   495.95    1735.65
1108          8/31/2013   495.95    1735.65
1108          8/31/2013   633.85    1735.65
1108          8/31/2013   19.95     1735.65
1205          8/3/2013    2389.09   2389.09

そして、以前の質問[Here]から得た答えを使用すると、SQL が完全に理解できていないと思います....

それで .....

次のようなデータを取得する必要があります。

SalesPersonID   1       2       3       4       5     6     7     8     9      ….  29    30      31
1108            0.00    7713.80 3635.35 3151.68 0.00  0.00  0.00  0.00  1413.80    0.00  1396.43 1735.65
1205            0.00    0.00    2389.09 0.00    0.00  0.00  0.00  0.00  0.00       0.00  0.00    0.00

上部の数字は、選択した月の日です。私は 8 月を使用しています。6 月を選択した場合、30 日しかありません。

このコードを使用して、最初と最後の日と日付を取得します。

DECLARE @BeginDate AS VARCHAR(10), @EndDate AS VARCHAR(10), @SelectedMonthDays AS int
SET @BeginDate='08/15/13'

-- Last Day of Current Month
Set @SelectedMonthDays = DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@BeginDate)+1,0)))

-- Last day Date of Current Month
SET @EndDate=cast(convert(date,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@BeginDate)+1,0))) as varchar(10))

-- Convert input date to the first day Date of current month
Set @BeginDate = cast(convert(date,DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,@BeginDate),0))) as varchar(10))

現在選択されている月の日を取得するには、次のコードを使用します。

SELECT xhours = number FROM Master..spt_values WHERE type = N'P' and number between 1 and @SelectedMonthDays ORDER BY number

皆様のご協力に感謝いたします。

4

1 に答える 1

3

このタイプのデータ変換はPIVOTと呼ばれます。

必要な値が事前にわかっている場合は、クエリをハードコードすることができ、基本的な構文は次のようになります。

SELECT salespersonid, 
       COALESCE([1], 0.00)  AS [1], 
       COALESCE([2], 0.00)  AS [2], 
       COALESCE([3], 0.00)  AS [3], 
       COALESCE([4], 0.00)  AS [4]
FROM   
(
    SELECT salespersonid, 
        [order], 
        Datepart(day, transdate) day 
    FROM   yourtable 
    WHERE  transdate >= '2013-08-01' 
        AND transdate <= '2013-08-31'
) x 
PIVOT 
(
    Sum([order]) 
    FOR day IN ([1], [2], [3], [4]) 
) p 

ただし、各月の日数に基づいて結果を調整したい状況では、動的 SQL を使用して確認する必要があります。を使用して既存のクエリを使用して、Master..spt_valuesそのリストを文字列に配置するだけで日付のリストを取得できます。動的 SQL コードは次のようになります。

DECLARE @BeginDate AS VARCHAR(10), @EndDate AS VARCHAR(10), @SelectedMonthDays AS int
SET @BeginDate='08/15/13'

-- Last Day of Current Month
Set @SelectedMonthDays = DATEPART(day, DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@BeginDate)+1,0)))

-- Last day Date of Current Month
SET @EndDate=cast(convert(date,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,@BeginDate)+1,0))) as varchar(10))

-- Convert input date to the first day Date of current month
Set @BeginDate = cast(convert(date,DATEADD(s,0,DATEADD(mm, DATEDIFF(m,0,@BeginDate),0))) as varchar(10))


DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(number) 
                    from Master..spt_values 
                    WHERE type = N'P' 
                      and number between 1 and @SelectedMonthDays 
                    group by number
                    ORDER BY number
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT ', coalesce(' + QUOTENAME(number)+', 0.00) as '+QUOTENAME(number)
                    from Master..spt_values 
                    WHERE type = N'P' 
                      and number between 1 and @SelectedMonthDays 
                    group by number
                    ORDER BY number
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT SalesPersonID, ' + @colsNull + ' 
            from 
            (
                select SalesPersonID, [Order], 
                  datepart(day, TransDate) day
                from yourtable
                where TransDate>= '''+convert(varchar(10), @BeginDate, 120)+'''
                  and TransDate<= '''+convert(varchar(10), @EndDate, 120)+'''
            ) x
            pivot 
            (
                sum([Order])
                for day in (' + @cols + ')
            ) p '


execute sp_executesql @query;

SQL Fiddle with Demoを参照してください。これにより、次の結果が得られます。

| SALESPERSONID | 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 | 29 |      30 |      31 |
|          1108 | 0 | 7713.8 | 3635.35 | 3151.68 | 0 | 0 | 0 | 0 | 1413.8 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 | 1396.43 | 1735.65 |
|          1205 | 0 |      0 | 2389.09 |       0 | 0 | 0 | 0 | 0 |      0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |  0 |       0 |       0 |
于 2013-09-05T19:33:01.093 に答える