首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

sql行转列的统计有关问题

2013-10-01 
sql行转列的统计问题ssmd是店名,mddm是店代码,两个是一致的表示一家店,店名和点代码是唯一的,zyj总业绩就

sql行转列的统计问题

ssmd是店名,mddm是店代码,两个是一致的表示一家店,店名和点代码是唯一的,zyj总业绩就是我要统计的。如果写统计语句,统计成下面图片那样
sql行转列的统计有关问题
这是统计一个月的,行是店名,列是每个月的号数、合计,第一周的统计,第二周的统计、第三周的统计、第4天的统计、最高业绩、最低业绩、超三天的超千元的统计。


大家帮帮忙,给个思路或者给个sql语句。我是新手,写这个统计有很多的困难。
求相助
请思路
SQL 统计
[解决办法]
以下是行列转换的方法,你可以参考一下,另外你周统计的那些可以单独查,再UNION ALL组合到之前的表。没必要一步到位。另外你得说清楚你的周是怎么划分的,前7天算一周?那么第五周只有2天的那种怎么考虑你要说清楚。


--PIVOT的一般语法是:PIVOT(聚合函数(列) FOR 列 in (…) )AS P
--
--完整语法:
--table_source
--PIVOT(
--聚合函数(value_column)
--FOR pivot_column
--IN(<column_list>)
--)

--eg.
--静态SQL(要求已知列名)
DECLARE @TB TABLE(ID INT ,VALUE1 NVARCHAR(50),VALUE2 NVARCHAR(50))
INSERT INTO @TB
SELECT 1,'A','S1' UNION ALL
SELECT 1,'B','S2' UNION ALL
SELECT 1,'C','S3' UNION ALL
SELECT 2,'A','S1' UNION ALL
SELECT 2,'B','S2' UNION ALL
SELECT 2,'C','S3'

SELECT * FROM (SELECT * FROM @TB) A 
PIVOT (
MAX(VALUE2) FOR VALUE1 IN (A,B,C)--但这里写死了列名
) B

--eg.2
--动态SQL(由于用到字符串,因此表变量无法使用,改用临时表)
--DROP TABLE #TB

SELECT * INTO #TB FROM (
SELECT 1 id,'A' Value1,'S1' Value2 UNION ALL
SELECT 1,'B','S2' UNION ALL
SELECT 1,'C','S3' UNION ALL
SELECT 2,'A','S1' UNION ALL
SELECT 2,'B','S2' UNION ALL
SELECT 2,'C','S3')A

DECLARE @SQL VARCHAR(MAX)
SELECT @SQL = ISNULL(@SQL + '],[' , '') + Value1 from #TB GROUP BY Value1
SET @SQL = '[' + @SQL + ']'

EXEC ('SELECT * FROM (SELECT * FROM #TB) D PIVOT (MAX(VALUE2) FOR VALUE1 IN ('+@SQL+')) B')

[解决办法]
--楼主没给 每日销售表?
--假如每日销售表就是图片中的上半部分的话,那么下半部分的统计参考如下:
SELECT 
[第一周] = SUM(CASE WHEN DAY(日期) BETWEEN 1 AND 7 THEN 销售金额 END),
[第二周] = SUM(CASE WHEN DAY(日期) BETWEEN 8 AND 14 THEN 销售金额 END),
[第三周] = SUM(CASE WHEN DAY(日期) BETWEEN 15 AND 21 THEN 销售金额 END),
[第四周] = SUM(CASE WHEN DAY(日期) BETWEEN 22 AND 28 THEN 销售金额 END),
[第五周] = SUM(CASE WHEN DAY(日期) BETWEEN 29 AND 31 THEN 销售金额 END),
[最高业绩] = MAX(销售金额),
[最低业绩] = ISNULL(MIN(销售金额), 0),
[超3千天数] = SUM(CASE WHEN 销售金额 >= 3000 THEN 1 ELSE 0 END)
FROM #tb--每日销售表
WHERE MONTH(日期) = 6

--如果图片上半部分数据不是现成的,一般都是通过行转列的方法完成的.网上的例子太多啦,不再多说

[解决办法]
楼主自己写一下吧
#1.行转列,缓存到一个临时表#A
#2.计算临时表#A,得到汇总表B
#3.SELECT * FROM #A UNION ALL SELECT * FROM B,应该就是楼主要的结果了
[解决办法]
引用:
Quote: 引用:
就是上面的那种图,能把一整个和起来,写给我吗?

--楼主刚发的帖子为何又删除了?
select ssmd,mddm,
sum(case when datepart(dd,tjrq)=1 then convert(decimal(18,2),zyj) else 0 end) as [1],
sum(case when datepart(dd,tjrq)=2 then convert(decimal(18,2),zyj) else 0 end) as [2],
sum(case when datepart(dd,tjrq)=3 then convert(decimal(18,2),zyj) else 0 end) as [3],
sum(case when datepart(dd,tjrq)=4 then convert(decimal(18,2),zyj) else 0 end) as [4],
sum(case when datepart(dd,tjrq)=30 then convert(decimal(18,2),zyj) else 0 end) as [30],
sum(case when datepart(dd,tjrq)=31 then convert(decimal(18,2),zyj) else 0 end) as [31],
sum(convert(decimal(18,2),zyj))as totel,
sum(case when datepart(dd,tjrq)between 1 and 7 then convert(decimal(18,2),zyj) else 0 end) as [第1周],
sum(case when datepart(dd,tjrq)between 8 and 14 then convert(decimal(18,2),zyj) else 0 end) as [第2周],
sum(case when datepart(dd,tjrq)between 15 and 21 then convert(decimal(18,2),zyj) else 0 end) as [第3周],


sum(case when datepart(dd,tjrq)between 22 and 28 then convert(decimal(18,2),zyj) else 0 end) as [第4周],
sum(case when datepart(dd,tjrq)between 29 and 31 then convert(decimal(18,2),zyj) else 0 end) as [第5周] 
from SJZL_ERP_MD_GRMRYJMX where convert(varchar(7),tjrq,120)='2013-06'group by ssmd,mddm

--先列转行,再行转列,再统计即可,假如你上面SQL统计出的结果为:
--1.不足的天数字段,自己补齐;不足门店名称字段,自己补齐,如果门店名称不固定,自己拼SQL
DECLARE @temp table(ssmd nvarchar(50), mddm nvarchar(50), [1] int, [2] int, [3] int, [31] int, [第1周] int, [第2周] int, [第3周] int, [第4周] int, [第5周] int)
INSERT @temp
SELECT '门店1', '0001', 1, 2, 3, 31, 11, 22, 33, 44, 55 UNION ALL
SELECT '门店2', '0002', 1, 2, 3, 31, 11, 22, 33, 44, 55

;WITH cte AS
(
SELECT * FROM 
(SELECT ssmd,[1],[2],[3],[31],[第1周],[第2周],[第3周],[第4周],[第5周] FROM @temp) a
UNPIVOT
(营业额 FOR [6月] IN([1],[2],[3],[31],[第1周],[第2周],[第3周],[第4周],[第5周])) b
PIVOT
(MAX(营业额) FOR ssmd IN([门店1], [门店2])) c
)
SELECT * FROM cte
UNION ALL
SELECT '最高业绩', MAX([门店1]), MAX([门店2]) FROM cte
UNION ALL
SELECT '最低业绩', MIN([门店1]), MIN([门店2]) FROM cte
UNION ALL
SELECT '超过3天的天数', SUM(CASE WHEN [门店1]>3 THEN 1 END), SUM(CASE WHEN [门店2]>3 THEN 1 END) FROM cte

/*
6月门店1门店2
111
222
333
313131
第1周1111
第2周2222
第3周3333
第4周4444
第5周5555
最高业绩5555
最低业绩11
超过3天的天数66
*/

热点排行