web-dev-qa-db-ja.com

動的日付ピボット

StartKPAテーブルのサンプルデータ:

enter image description here

私は次のクエリを書きました:

SELECT      *
FROM    
(
            SELECT BookInventoryDate, EndKpa,CASE WHEN (EndKPA*100)>80 THEN '>80' WHEN (EndKPA*100) BETWEEN 70 AND 80 THEN '70-80'
                                              WHEN (EndKPA*100) BETWEEN 65 AND 70 THEN '65-70'
                                              WHEN (EndKPA*100) BETWEEN 62 AND 65 THEN '62-65'
                                              WHEN (EndKPA*100) BETWEEN 60 AND 62 THEN '60-62'
                                              ELSE '<60' END as Aantallen
FROM        StartKPA
WHERE       BookInventoryDate > '20180429'
)           as Aantallen
PIVOT
(
    COUNT(EndKpa)
    FOR [BookInventoryDate] IN ([20180430], [20180501], [20180502])
) AS pvt
ORDER BY Aantallen DESC

次の結果が表示されます(申し訳ありませんが、ここのテーブルに入れることができませんでした):

enter image description here

問題は、動的な日付が欲しいということです。したがって、毎日新しい日付が追加され、データがないため20180502は表示されません。したがって、上記の表の結果が必要ですが、毎日新しい日が追加されます(上記のようなゼロの結果はありません)。クエリに毎日新しい日付を手動で追加したくありません。

すでにいくつかの投稿がありますが、機能させることができませんでした。

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

;with cte (datelist, maxdate) as
(
select min(BookInventoryDate) datelist, max(BookinventoryDate) maxdate
from StartKPA
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
) 
select c.datelist
into #tempDates
from cte c

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), 
datelist, 120)) 
                from #tempDates
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @query = 'SELECT Aantallen, BookinventoryDate, ' + @cols + ' from 
         (
           SELECT BookInventoryDate, EndKpa,CASE WHEN (EndKPA*100)>80 THEN '>80' WHEN (EndKPA*100) BETWEEN 70 AND 80 THEN '70-80'
                                              WHEN (EndKPA*100) BETWEEN 65 AND 70 THEN '65-70'
                                              WHEN (EndKPA*100) BETWEEN 62 AND 65 THEN '62-65'
                                              WHEN (EndKPA*100) BETWEEN 60 AND 62 THEN '60-62'
                                              ELSE '<60' END as Aantallen
            FROM        #tempDates d
            LEFT JOIN   StartKPA kpa on d.datelist=kpa.bookinventorydate
            WHERE       BookInventoryDate > '20180429'
        ) x
        pivot 
        (
            count(EndKpa)
            for PivotDate in (' + @cols + ')
        ) p '

execute(@query)

いくつかのエラーメッセージが表示され、変更しようとしましたが、機能させるために十分に理解できません。

誰かがお手伝いできますか?ありがとう!

4
SqlUser

このクエリを試してください。データがないため、クエリを確認できませんでした。エラーがある場合はお知らせください。

SELECT DISTINCT BookInventoryDate FROM StartKPA

DECLARE @colsValues AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename(datesYouWantAsColumns)
         FROM yourTable
         FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

StartKPAがテーブルであり、BookInventoryDateがそのテーブルのフィールドであると想定して、一意の日付を取得しています。間違っている場合は変更してください。

DECLARE @colsValues AS NVARCHAR(max) = Stuff((SELECT DISTINCT ',' + Quotename(BookInventoryDate)
         FROM StartKPA
         FOR xml path(''), type).value('.', 'NVARCHAR(MAX)'), 1, 1, ''); 

DECLARE @query AS NVARCHAR(max);

SET @query =   'SELECT      *
                FROM    
                (
                            SELECT BookInventoryDate, EndKpa,CASE WHEN (EndKPA*100)>80 THEN ''>80'' WHEN (EndKPA*100) BETWEEN 70 AND 80 THEN ''70-80''
                                                                WHEN (EndKPA*100) BETWEEN 65 AND 70 THEN ''65-70''
                                                                WHEN (EndKPA*100) BETWEEN 62 AND 65 THEN ''62-65''
                                                                WHEN (EndKPA*100) BETWEEN 60 AND 62 THEN ''60-62''
                                                                ELSE ''<60'' END as Aantallen
                FROM        StartKPA
                WHERE       BookInventoryDate > ''20180429''
                )           as Aantallen
                PIVOT
                (
                    COUNT(EndKpa)
                    FOR [BookInventoryDate] IN ('+ @colsValues +')
                ) AS pvt
                ORDER BY Aantallen DESC';

EXECUTE(@query); 
1
DxTx

一重引用符を変更する必要があります'二重引用符で@query内に''

再帰クエリを使用していることに注意してください。正しい値を設定する必要があります。

OPTION (MAXRECURSION XXXX)
create table StartKPA(BookInventoryDate datetime);
insert into StartKPA values ('20180101'), ('20180108');
GO
 2行が影響を受けました
DECLARE @cols AS NVARCHAR(MAX),
@query  AS NVARCHAR(MAX)

;with cte (datelist, maxdate) as
(
select min(BookInventoryDate) datelist, max(BookinventoryDate) maxdate
from StartKPA
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
) 
select c.datelist
into #tempDates
from cte c
option (maxrecursion 0);

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(CHAR(10), 
datelist, 120)) 
                from #tempDates
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @query = 'SELECT Aantallen, BookinventoryDate, ' + @cols + ' from 
         (
           SELECT BookInventoryDate, EndKpa,CASE WHEN (EndKPA*100)>80 THEN ''>80'' WHEN (EndKPA*100) BETWEEN 70 AND 80 THEN ''70-80''
                                              WHEN (EndKPA*100) BETWEEN 65 AND 70 THEN ''65-70''
                                              WHEN (EndKPA*100) BETWEEN 62 AND 65 THEN ''62-65''
                                              WHEN (EndKPA*100) BETWEEN 60 AND 62 THEN ''60-62''
                                              ELSE ''<60'' END as Aantallen
            FROM        #tempDates d
            LEFT JOIN   StartKPA kpa on d.datelist=kpa.bookinventorydate
            WHERE       BookInventoryDate > ''20180429''
        ) x
        pivot 
        (
            count(EndKpa)
            for PivotDate in (' + @cols + ')
        ) p '

select @query;
GO
SELECT Aantallen, BookinventoryDate, [2018-01-01],[2018-01-02],[2018-01-03],[2018-01-04],[2018-01-05],[2018-01-06],[2018-01-07],[2018-01-08] from 
         (
           SELECT BookInventoryDate, EndKpa,CASE WHEN (EndKPA*100)>80 THEN '>80' WHEN (EndKPA*100) BETWEEN 70 AND 80 THEN '70-80'
                                              WHEN (EndKPA*100) BETWEEN 65 AND 70 THEN '65-70'
                                              WHEN (EndKPA*100) BETWEEN 62 AND 65 THEN '62-65'
                                              WHEN (EndKPA*100) BETWEEN 60 AND 62 THEN '60-62'
                                              ELSE '<60' END as Aantallen
            FROM        #tempDates d
            LEFT JOIN   StartKPA kpa on d.datelist=kpa.bookinventorydate
            WHERE       BookInventoryDate > '20180429'
        ) x
        pivot 
        (
            count(EndKpa)
            for PivotDate in ([2018-01-01],[2018-01-02],[2018-01-03],[2018-01-04],[2018-01-05],[2018-01-06],[2018-01-07],[2018-01-08])
        ) p 

db <> fiddle ここ

1
McNets