akhter86 Ответов: 1

Итоговое значение по строкам и столбцам в pivot


Я хочу, чтобы строка мудрая и столбец мудрый итог

Create table #Sections (SecID int, Secnam varchar(50))
create table #ItemMasterFile(CodeItem int, Descriptionitem varchar(max),SecID int,CID int)
create table #Probale (BID int, CodeItem int,   prdqtyint,EntryDate date)


insert into #Sections 
values
(1, 'HR'),
(2, 'Baby'),
(3, 'Ladies'),
(4, 'Mix Rammage'),

insert into #ItemMasterFile
values
(1, 'A',  '1'),
(2, 'B',  '2'),
(3, 'C',  '3'), 
(4, 'D' ,'4')


insert into #Probale
values
(1, '1', '1', '5/01/2019 '),
(2, '2', '1', '5/01/2019 '),
(3, '3', '1', '5/01/2019 '),
(4, '2', '1', '5/02/2019 '),
(5, '3', '1', '5/02/2019 '),
(6, '4', '1', '5/02/2019 '),
(6, '1', '1', '5/03/2019 '),
(7, '2', '1', '5/04/2019 '),
(8, '4', '1', '5/05/2019 '),


Что я уже пробовал:

вот моя процедура в магазине

Create Procedure [dbo].[Pivot_Item1] @StartDate Date,
@Enddate Date

AS
BEGIN
DECLARE @cols AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.

SET NOCOUNT ON;

SELECT Distinct Entrydate INTO #Dates26 FROM Probale WHERE EntryDate BETWEEN @StartDate AND @Enddate ORDER BY EntryDate

SELECT @cols = COALESCE(@cols + ',','') + QUOTENAME( CONVERT(varchar(2),EntryDate) )
FROM (SELECT DISTINCT DATEPART(DAY, EntryDate) AS EntryDate FROM #Dates26 ) T
ORDER BY EntryDate

--SET @cols = STUFF(@cols, 1, 1, '')


SET @query =
N'SELECT *
FROM (SELECT Descriptionitem,Probale.prdqty,
DATEPART(DAY, Probale.EntryDate)as DDate
FROM Probale left JOIN ItemMasterFile on ItemMasterFile.Codeitem=Probale.Codeitem
where Probale.DelID is Null and Probale.EntryDate BETWEEN @StartDate AND @Enddate )prd
PIVOT (Sum(prdqty) FOR DDate IN (' + @cols + ')) AS stat'
exec sp_executesql @query , N'@StartDate datetime,@enddate datetime', @StartDate=@StartDate,@Enddate=@Enddate

END

OriginalGriff

И что же?
Что он делает такого, чего вы не ожидали, или не делает того, что вы сделали?
Какая помощь вам нужна?

akhter86

Дорогой OriginalGriff,
Я хочу, чтобы строки и столбца мудрый общей сложности,выше хранимая процедура просто отображение даты мудрый общего элемента,теперь я хочу, чтобы строки общая или каждого элемента и столбца мудрый итог каждого дня.

OriginalGriff

И что же вы пытались сделать для этого?
Что это дало, и что вы сделали, чтобы попытаться исправить это?
Какие ошибки вы получили?

akhter86

Дорогой OriginalGriff,
я попробовал это ( ALTER Procedure [dbo].[Pivot_Item2]
@StartDate Дата,
@Дата Окончания Срока Действия

АС
НАЧАТЬ
Объявите @cols как NVARCHAR(макс.)
Объявить @query как NVARCHAR(MAX)
объявить @sum nvarchar(max);
Выберите @сумма= КОАЛЕСЦИРУЮТ(@сумма + ',',") + ('сумма('+функции quotename(prdqty)+')') от Probale;
-- Установить параметр nocount на добавленную предотвратить дополнительные результирующие наборы
-- вмешательство в операторы SELECT.

УСТАНОВИТЕ NOCOUNT ON;




Выберите Distinct Entrydate в #Dates26
Из Пробейла
Где EntryDate между @StartDate и @Enddate
Заказ по EntryDate



Выберите @седла = КОАЛЕСЦИРУЮТ(@гуара + ',',") + функции quotename( конвертировать(тип varchar(10),EntryDate) )
--Из (выбрать различные функции datepart(день, EntryDate) как EntryDate от #Dates26 ) Т
FROM (выберите DISTINCT EntryDate как EntryDate FROM #Dates26 ) T
Заказ по EntryDate

--SET @cols = STUFF(@cols, 1, 1, ")


SET @query =
N ' with cte as (SELECT *,(select sum(prdqty) from Probale where CONVERT(varchar(10), EntryDate) =stat.ddate ) as total


FROM (SELECT Descriptionitem,Probale.prdqty,

Конвертация(varchar(10),Probale.EntryDate) как DDate
Из Probale слева присоединяйтесь к ItemMasterFile на ItemMasterFile.Codeitem=Probale.Codeitem
где Пробале.DelID - это Null и Probale.EntryDate между @StartDate и @Enddate )prd
PIVOT (Sum(prdqty) FOR DDate IN (' + @cols + ')) Как стат)

выберите * из cte

союз всех
выберите 0,'+@sum+', (select sum(prdqty ) from Probale ) from cte'

метод exec sp_executesql процедура запроса@, Н@начальная дата типа datetime,@enddate в тип datetime', @начальная дата=@дата StartDate,@параметр enddate=@enddate в


КОНЕЦ
)

приходит ошибка ( недопустимое имя столбца "ddate".)

1 Ответов

Рейтинг:
5

CHill60

Во - первых, вам нужно исправить код, который вы используете для создания таблиц-в настоящее время он производит эти ошибки

Msg 173, Уровень 15, Состояние 1, Строка 3
Определение столбца 'prdqtyint' должно содержать тип данных.
Msg 156, Уровень 15, Состояние 1, Строка 13
Неправильный синтаксис около ключевого слова 'вставить'.
Msg 102, Уровень 15, Состояние 1, Строка 31
Неправильный синтаксис рядом с ','.
Как только вы исправите их, вы получите еще одну ошибку
Msg 213, Уровень 16, Состояние 1, Строка 13
Имя столбца или количество предоставленных значений не соответствует определению таблицы.
Потому что значения, которые вы вставляете в #ItemMasterFile не соответствует определению таблицы. Вы также сделали это с помощью #Probale где вы проходите varchar значения в int столбцы, но SQL преобразовал это для вас.

Я благодарю вас за то, что вы дали нам код для воссоздания ваших таблиц данных, но для дальнейшего использования ваше отсутствие заботы об этом заставит многих членов просто сдаться.

Проблема сохраняется, когда я начинаю изучать ваш динамический запрос -
Msg 207, Уровень 16, Состояние 1, Линия 78
DelID недопустимое имя столбца''.
Я просто удалил это из своей версии.

Кстати, мне тоже не нравится непоследовательность этих слов.
exec sp_executesql @query , N'@StartDate datetime,@enddate datetime', @StartDate=@StartDate,@Enddate=@Enddate
EntryDate - это a date так зачем же начинать использовать datetime Итак, я наконец-то получил ваши результаты.
Descriptionitem	1	2	3	4	5
A	1	NULL	1	NULL	NULL
B	1	1	NULL	1	NULL
C	1	1	NULL	NULL	NULL
D	NULL	1	NULL	NULL	1
Вот тут-то и вступают в игру комментарии @OriginalGriff. Вы не приложили никаких усилий, чтобы сделать это для себя. Так …

Чтобы получить общее количество строк, вам нужно будет сложить все столбцы вместе. Используйте ту же технику, которую вы использовали, чтобы получить @cols но обратите внимание, что вам придется иметь дело с этими нулевыми значениями - я предлагаю использовать что-то вроде
SELECT Descriptionitem, ISNULL([1],0) AS [1], … etc
Чтобы получить итоговые значения столбцов вам нужно будет UNION запрос, который просто суммирует столбцы. Я поместил ваш pivot в общее табличное выражение, чтобы сделать это проще, и добавил
UNION 
SELECT 'Total', SUM([1]), SUM([2]),SUM([3]),sum([4]),sum([5]), SUM(([1] + [2] + [3] + [4] + [5])) AS RowTotal
from CTE
Обратите внимание, что мне не нужно беспокоиться о ISNULL, потому что SUM будет обрабатывать нулевые значения для меня.
Но также обратите внимание, что я должен был включить сумму rowtotals, чтобы заставить Союз работать


akhter86

Дорогой Chill60

Я сделал запрос на объединение вот мой порядок в магазине ...

я попробовал это ( ALTER Procedure [dbo].[Pivot_Item2]
@StartDate Дата,
@Дата Окончания Срока Действия

АС
НАЧАТЬ
Объявите @cols как NVARCHAR(макс.)
Объявить @query как NVARCHAR(MAX)
объявить @sum nvarchar(max);
Выберите @сумма= КОАЛЕСЦИРУЮТ(@сумма + ',',") + ('сумма('+функции quotename(prdqty)+')') от Probale;
-- Установить параметр nocount на добавленную предотвратить дополнительные результирующие наборы
-- вмешательство в операторы SELECT.

УСТАНОВИТЕ NOCOUNT ON;




Выберите Distinct Entrydate в #Dates26
Из Пробейла
Где EntryDate между @StartDate и @Enddate
Заказ по EntryDate



Выберите @седла = КОАЛЕСЦИРУЮТ(@гуара + ',',") + функции quotename( конвертировать(тип varchar(10),EntryDate) )
--Из (выбрать различные функции datepart(день, EntryDate) как EntryDate от #Dates26 ) Т
FROM (выберите DISTINCT EntryDate как EntryDate FROM #Dates26 ) T
Заказ по EntryDate

--SET @cols = STUFF(@cols, 1, 1, ")


SET @query =
N ' with cte as (SELECT *,(select sum(prdqty) from Probale where CONVERT(varchar(10), EntryDate) =stat.ddate ) as total


FROM (SELECT Descriptionitem,Probale.prdqty,

Конвертация(varchar(10),Probale.EntryDate) как DDate
Из Probale слева присоединяйтесь к ItemMasterFile на ItemMasterFile.Codeitem=Probale.Codeitem
где Пробале.DelID - это Null и Probale.EntryDate между @StartDate и @Enddate )prd
PIVOT (Sum(prdqty) FOR DDate IN (' + @cols + ')) Как стат)

выберите * из cte

союз всех
выберите 0,'+@sum+', (select sum(prdqty ) from Probale ) from cte'

метод exec sp_executesql процедура запроса@, Н@начальная дата типа datetime,@enddate в тип datetime', @начальная дата=@дата StartDate,@параметр enddate=@enddate в


КОНЕЦ
)
но
приходит ошибка ( недопустимое имя столбца "ddate".)

CHill60

Во первых взгляните на вашу переменную @sumЭто значение

sum([1]),sum([1]),sum([1]),sum([1]),sum([1]),sum([1]),sum([1]),sum([1]),sum([1])
- Совсем не то, что ты хочешь. Переместите его вниз на после того, как вы заполнили #Dates26 и используете правильную таблицу, т. е.
SELECT @sum= COALESCE(@sum + ',','') + ('sum('+QUOTENAME(Entrydate)+')') FROM (SELECT DISTINCT EntryDate AS EntryDate FROM #Dates26 ) TORDER BY EntryDate
что даст вам
[2019-05-01],[2019-05-02],[2019-05-03],[2019-05-04],[2019-05-05]
Вам также понадобится другой переменная, которая даст вам
ISNULL([2019-05-01],0) AS [2019-05-01]...etc
Используйте ту же технику. Вы также полностью проигнорировали пункт о ISNULL и необходимости складывать столбцы вместе, чтобы получить общее количество строк
Решив все это поставьте свой оригиналвернитесь в тело CTE - я понятия не имею, чего вы пытаетесь достичь с помощью этих подзапросов. Избавься от них.
Ваш окончательный запрос должен выглядеть примерно так
;with cte as 
(	
     SELECT Descriptionitem, ISNULL([2019-05-01],0) AS [2019-05-01], ISNULL([2019-05-02],0) AS [2019-05-02],
	 		ISNULL([2019-05-03],0) AS [2019-05-03], ISNULL([2019-05-04],0) AS [2019-05-04],
 		ISNULL([2019-05-05],0) AS [2019-05-05]	
 	FROM 	
 	(		
 	 	SELECT Descriptionitem,#Probale.prdqty, #Probale.EntryDate as DDate		
 	 	FROM #Probale 		
 	 	left JOIN #ItemMasterFile on #ItemMasterFile.Codeitem=#Probale.Codeitem		
 	 	where --#Probale.DelID is Null and 
 	 	#Probale.EntryDate BETWEEN @StartDate AND @Enddate 	
 	)prd	
 	PIVOT 	
 	(		
 	 	Sum(prdqty) FOR DDate IN ([2019-05-01],[2019-05-02],[2019-05-03],[2019-05-04],[2019-05-05])	
 	) AS stat
)
select Descriptionitem, [2019-05-01],[2019-05-02],[2019-05-03],[2019-05-04],[2019-05-05],  		
([2019-05-01]+[2019-05-02]+[2019-05-03]+[2019-05-04]+[2019-05-05]) AS RowTotal
from cte
union
select 'Total',sum([2019-05-01]),sum([2019-05-02]),sum([2019-05-03]),sum([2019-05-04]),sum([2019-05-05]), 		
SUM([2019-05-01]+[2019-05-02]+[2019-05-03]+[2019-05-04]+[2019-05-05]) as ColumnTotal
from cte

Воспользуйся
PRINT @query
вместо того, чтобы exec пока у вас нет правильного запроса и вы не используете гораздо больше CRLF и пробелов - гораздо легче увидеть, что происходит

akhter86

большое спасибо за ваше руководство, я никогда не использовал хардкорные значения в запросе, понятия не имею, как это будет сделано [2019-05-01],[2019-05-02],[2019-05-03],[2019-05-04],[2019-05-05], так что все еще ищем решение ,,,

CHill60

Вы уже создали этот список имен столбцов в твой оригинальный пост!

SELECT @cols = COALESCE(@cols + ',','') + QUOTENAME( CONVERT(varchar(2),EntryDate) )
FROM (SELECT DISTINCT DATEPART(DAY, EntryDate) AS EntryDate FROM #Dates26 ) T
ORDER BY EntryDate
Единственная разница заключается в том, что во второй попытке в комментариях вы больше не используете DATEPART и используете всю дату в качестве имени столбца. Я не понимаю, почему вы все еще ищете решение

Maciej Los

5ed!