Объединение нескольких динамических сводных таблиц

Я не видел такого вопроса, но если есть ответ, на который был дан ответ, пожалуйста, дайте мне знать.

Мне нужно создать экспорт, используя хранимую процедуру. К сожалению, в настоящее время создание этого отчета в службах SSRS невозможно.

Что мне нужно сделать, так это динамически создать сводную таблицу и объединить ее с другой - или это то, что я думал, сработает.

Необработанные данные работают примерно так (я изменил элементы для защиты данных моей компании):

Образец данных

Они хотят, чтобы данные в отчете выглядели следующим образом (для экономии места я не использовал все даты, но вы можете понять идею): Образец отчета

Я создал временную таблицу и создал две динамические сводные таблицы. Обе таблицы будут работать отдельно, но как только я использую UNION ALL, я получаю сообщение об ошибке (я добавлю это ниже). Я включаю код, который использовал для создания двух опорных точек. Может кто-нибудь сказать мне, что я делаю неправильно?

Можно ли сделать это всего за один стержень?

/*
    Use dynamic SQL to find all 
    Issue Dates for column headings
*/
DECLARE @Jquery VARCHAR(8000)
DECLARE @query VARCHAR(4000)
DECLARE @years VARCHAR(2000)
SELECT  @years = STUFF(( SELECT DISTINCT
                        '],[' + 'Item 1' + ' ' + (IssueDate)
                        FROM    #GroupData GroupData
                        ORDER BY '],[' + 'Item 1' + ' ' + (IssueDate)
                        FOR XML PATH('')
                        ), 1, 2, '') + ']'

SET @query =
'SELECT * FROM
(
    SELECT LocationID, StoreName, StoreState AS State, "Item 1" + " " + (IssueDate) AS IssueDate, MoneyOrder
    FROM #GroupData GroupData
) MoneyOrderIssued
PIVOT (MAX(MoneyOrder) FOR IssueDate
IN ('+@years+')) AS pvt'

DECLARE @queryMOUsed VARCHAR(4000)
DECLARE @MOUsedYear VARCHAR(2000)
SELECT  @MOUsedYear = STUFF(( SELECT DISTINCT
                        '],[' + 'Item 2' + ' ' + (IssueDate)
                        FROM    #GroupData GroupData
                        ORDER BY '],[' + 'Item 2' + ' ' + (IssueDate)
                        FOR XML PATH('')
                        ), 1, 2, '') + ']'

SET @queryMOUsed =
'SELECT * FROM
(
    SELECT LocationID, StoreName, StoreState AS State, "Item 2" + " " + (IssueDate) AS IssueDate, MOUsed
    FROM #GroupData GroupData
)SCRMoneyOrders
PIVOT (MAX(MOUsed) FOR IssueDate
IN ('+@MOUsedYear+')) AS pvt'

SET @Jquery = @query + ' UNION ALL ' +  @queryMOUsed


EXECUTE (@query) -- Only in here to show that this works w/out UNION ALL
EXECUTE (@queryMOUsed) -- Only in here to show that this works w/out UNION ALL

EXECUTE (@Jquery)

Сообщение об ошибке, которое я получаю, выглядит следующим образом:

Предупреждение: нулевое значение устраняется агрегатной или другой операцией SET. Сообщение 8114, уровень 16, состояние 5, строка 1 Ошибка преобразования типа данных varchar в bigint.


person DataGirl    schedule 04.05.2011    source источник


Ответы (2)


Моя идея заключается в том, что столбцы не совпадают (по количеству столбцов, порядку столбцов и типу данных). Если я правильно понимаю ваш запрос, если даты выпуска для item1 и item2 не совпадают, вы все равно можете получить несоответствующие столбцы. Трудно сказать, не видя результатов этих двух запросов.

Вы уверены, что не хотите ПРИСОЕДИНЯТЬСЯ на основе идентификатора магазина?

Что-то вроде :

WITH Item1Data as (
--pivot query for item 1
),
Item2Data as (
 --pivot query for item 2
)
SELECT columns
FROM Item1DATA i1
LEFT JOIN Item2Data i2
ON i1.SoteID = i2.StoreID

Вот динамический запрос, который я сделал. получили столбцы, сгенерированные данными:

 --Get string of aggregate columns for pivot.  The aggregate columns are the last 5 NRS Years.
                    DECLARE @aggcols NVARCHAR(MAX)

                    SELECT  @aggcols = STUFF(( SELECT   '],['
                                                        + CAST(ny2.NRS_YEAR AS CHAR(4))
                                               FROM     mps.NRS_YEARS ny2
                                               WHERE    ny2.NRS_YEAR BETWEEN @NRS_Year
                                                        - 5 AND @NRS_Year
                                               ORDER BY '],['
                                                        + CAST(ny2.NRS_YEAR AS CHAR(4))
                                             FOR
                                               XML PATH('') ) , 1 , 2 , '')
                            + ']' ;

--While we're at it, get a sum of each year column.  we'll do a union query instead of  rollup because that's how we roll.

                    DECLARE @sumcols NVARCHAR(MAX) ;
                    SELECT  @sumcols = STUFF(( SELECT   ']),sum(['
                                                        + CAST(ny2.NRS_YEAR AS CHAR(4))
                                               FROM     mps.NRS_YEARS ny2
                                               WHERE    ny2.NRS_YEAR BETWEEN @NRS_Year
                                                        - 5 AND @NRS_Year
                                               ORDER BY ']),sum(['
                                                        + CAST(ny2.NRS_YEAR AS CHAR(4))
                                             FOR
                                               XML PATH('') ) , 1 , 3 , '')
                            + '])' ;

                    DECLARE @Query NVARCHAR(MAX) ;
--Construct dynamic pivot query

                    SET @Query = N'SELECT MonthName as Month, ' + @aggcols
                        + N'
      into ##MonthHourPivot
FROM
 (SELECT nc.MONTHNAME, nc.MonthOfNRS_Yr, nc.NRS_YEAR, st.Hours
 FROM mps.NRS_Calendar nc 
 INNER JOIN dbo.StudentTime st
 ON nc.Date = /*00:00:00 AM*/ DATEADD(dd, DATEDIFF(dd, 0, /*On*/ st.EntryDateTime), 0)
 LEFT JOIN mps.vw_ScheduleRoomBuilding srb
 ON st.ScheduleID = srb.ScheduleID
 WHERE (st.EntryDateTime <= GETDATE() and st.SiteCode = ''' + @SiteCode
                        + N''' or ''' + @SiteCode + N''' = ''All'')
 AND (srb.Abbreviation = ''' + @Building + N''' or ''' + @Building
                        + N''' = ''All'')) p
 PIVOT
 (
 sum(p.Hours)
 FOR NRS_Year IN
( ' + @aggcols + N' )
) AS pvt 
' ;

--Execute It.
                    EXECUTE(@Query) ;

                    SET @Query = N'Select [Month], ' + @aggcols
                        + N'FROM ##MonthHourPivot UNION ALL SELECT ''Total'' as [Month], '
                        + @sumcols + ' FROM ##MonthHourPivot' ;
                     Execute (@Query);
person NateMpls    schedule 04.05.2011
comment
Думаю, ты прав, Нейт. Наш администратор базы данных только что указал (как и пять минут назад), что я пытаюсь объединить два разных типа столбцов. В то время у нее не было ответа на вопрос, как ориентироваться на различные элементы, используя комбинацию дат. есть идеи? - person DataGirl; 04.05.2011
comment
Другой вопрос, вам нужно, чтобы элементы динамически генерировались? - person NateMpls; 04.05.2011
comment
Это отличный вопрос. Мне нужно, чтобы элементы генерировались динамически, потому что они основаны на датах из диапазона дат. Я, наверное, не очень хорошо объяснил. единственный способ использовать все даты в качестве заголовков столбцов — это динамически создать сводную таблицу. Позвольте мне попытаться объяснить это лучше: конечный пользователь вводит диапазон дат и выбирает магазин или магазины, которые он хочет видеть. Они хотят видеть продажи каждого товара на каждую дату. Итак, продажи товара 1 20 августа рядом с продажами товара 2 20 августа. - person DataGirl; 04.05.2011
comment
Дай мне секунду. Я пытаюсь найти исходный код, с которым вы могли бы работать. - person NateMpls; 04.05.2011
comment
Я обновил ответ динамическим запросом, который я сделал на основе года. Столбцы представляют собой 100% сгенерированные данные. Вы должны иметь возможность адаптировать его, соединив строки элемента и даты. - person NateMpls; 04.05.2011
comment
Спасибо, Нейт! Сейчас я просматриваю это и добавляю информацию для своих таблиц. Я очень ценю вашу помощь. Теперь я вижу, что шел не в том направлении. - person DataGirl; 04.05.2011
comment
Этот тип SQL работает, но его так сложно писать и отлаживать! Еще хуже, когда права пользователей ограничены, что может ограничить повторное использование кода. - person Richard; 14.08.2016

Это похоже на то, что более уместно сделать с помощью инструмента ETL.

Я не очень хорошо знаком с набором инструментов Microsoft, но я предполагаю, что в их пакете хранилища данных есть что-то для этого. В «Интеграции данных» Pentaho (Kettle) вы должны использовать шаг денормализации строк или шаг выравнивания строк.

person Community    schedule 04.05.2011
comment
Спасибо за ответ. К сожалению, я не могу использовать ETL. Хранимая процедура, которую я создам с помощью этой сводной таблицы, будет добавлена ​​в существующий продукт. - person DataGirl; 04.05.2011