SQL - 交叉表。一个字段的总和而不是列中的行数
SQL - Cross tab. Sum of a field instead of count rows in columns
目前正在尝试创建一个查询,以提供代理人全年按天计算的销售额。我已经设法使总计列起作用,但每日销售额却没有,从原始数据来看,似乎不是对特定代理人一天的总销售额求和,而是用它来计算所有行代理列出并输出它。
代码如下:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106))
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017'
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query =
' SELECT
[Advisor_Name] AS [Advisor_Name]
,[Line_Managers_Name] AS [Line_Managers_Name]
,[SALE_TYPE]
,[Total]
,'+ @cols +'
From (
Select
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE])
[Total]
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE]
From [Sales_Data] a with (NoLock)
) x
pivot
(
Count([ENTRY_DATE])
for [ENTRY_DATE] in (' + @cols + ')
) p
Order by [Advisor_Name], [Line_Managers_Name], [CHANNEL]
'
execute(@query)
如果我无法更改我计划的查询,而是更改源数据以逐行提供销售信息而不是汇总成一个总和,不幸的是,某些行可能有一个 -1 的客户sale 表示退款,我不知道如何适应这些,我已经尝试 select distinct,select from (select distinct.....) having count(* ) = 1,但似乎没有任何效果。
你能试试这个吗,我不得不尝试模拟你的数据,但看起来我得到了不错的结果。
SELECT
*
From (
Select distinct
sum([Total])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE], [ENTRY_DATE]) as Total
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE],
sum([Total])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE]) as TotalSales
From [Sales_Data] a with (NoLock)
) x
pivot
(
Sum(Total)
for [ENTRY_DATE] in ([01 Jan 2017],[02 Jan 2017],[03 Jan 2017])
) p
Order by [Advisor_Name], [Line_Managers_Name]
我还修改了动态生成的 SQL 以生成新的输出。
DECLARE @cols AS NVARCHAR(MAX)
DECLARE @colsForPivot AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',ISNULL(' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106)) + ',0)'
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017')
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsForPivot = STUFF((SELECT ',' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106))
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017')
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query =
'SELECT
[Advisor_Name], [Line_Managers_Name], [SALE_TYPE], ISNULL(TotalSales,0), '
+ @cols + '
From (
Select distinct
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE], [ENTRY_DATE])
[Total]
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE],
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE]) as TotalSales
From [Sales_Data] a with (NoLock)
) x
pivot
(
sum([Total])
for [ENTRY_DATE] in (' + @colsForPivot + ')
) p
Order by [Advisor_Name], [Line_Managers_Name]
'
print(@query)
目前正在尝试创建一个查询,以提供代理人全年按天计算的销售额。我已经设法使总计列起作用,但每日销售额却没有,从原始数据来看,似乎不是对特定代理人一天的总销售额求和,而是用它来计算所有行代理列出并输出它。 代码如下:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106))
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017'
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query =
' SELECT
[Advisor_Name] AS [Advisor_Name]
,[Line_Managers_Name] AS [Line_Managers_Name]
,[SALE_TYPE]
,[Total]
,'+ @cols +'
From (
Select
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE])
[Total]
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE]
From [Sales_Data] a with (NoLock)
) x
pivot
(
Count([ENTRY_DATE])
for [ENTRY_DATE] in (' + @cols + ')
) p
Order by [Advisor_Name], [Line_Managers_Name], [CHANNEL]
'
execute(@query)
如果我无法更改我计划的查询,而是更改源数据以逐行提供销售信息而不是汇总成一个总和,不幸的是,某些行可能有一个 -1 的客户sale 表示退款,我不知道如何适应这些,我已经尝试 select distinct,select from (select distinct.....) having count(* ) = 1,但似乎没有任何效果。
你能试试这个吗,我不得不尝试模拟你的数据,但看起来我得到了不错的结果。
SELECT
*
From (
Select distinct
sum([Total])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE], [ENTRY_DATE]) as Total
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE],
sum([Total])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE]) as TotalSales
From [Sales_Data] a with (NoLock)
) x
pivot
(
Sum(Total)
for [ENTRY_DATE] in ([01 Jan 2017],[02 Jan 2017],[03 Jan 2017])
) p
Order by [Advisor_Name], [Line_Managers_Name]
我还修改了动态生成的 SQL 以生成新的输出。
DECLARE @cols AS NVARCHAR(MAX)
DECLARE @colsForPivot AS NVARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',ISNULL(' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106)) + ',0)'
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017')
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsForPivot = STUFF((SELECT ',' + QUOTENAME(convert(varchar(20), [ENTRY_DATE], 106))
FROM [Sales_Data] with (NoLock)
where([ENTRY_DATE] between '01-Jan-2017' and '01-Jul-2017')
Group By [ENTRY_DATE]
order by [ENTRY_DATE]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query =
'SELECT
[Advisor_Name], [Line_Managers_Name], [SALE_TYPE], ISNULL(TotalSales,0), '
+ @cols + '
From (
Select distinct
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE], [ENTRY_DATE])
[Total]
, [ENTRY_DATE]
, [Advisor_Name]
, [Line_Managers_Name]
, [SALE_TYPE],
sum([SALES])
over(partition by [Advisor_Name], [Line_Managers_Name], [SALE_TYPE]) as TotalSales
From [Sales_Data] a with (NoLock)
) x
pivot
(
sum([Total])
for [ENTRY_DATE] in (' + @colsForPivot + ')
) p
Order by [Advisor_Name], [Line_Managers_Name]
'
print(@query)