把数据库表格里的行列按照日期转置

原创
04/18 17:08
阅读数 74
SELECT * FROM
(SELECT TOP (1000) *
FROM [HerPeisTJTLTJZX].[dbo].[viDd]
WHERE	nian ='2023' and yue='4'
)A



SELECT org,[1],[2],[3],[4],[5],[6],[7]
FROM [HerPeisTJTLTJZX].[dbo].[viDd]
	
PIVOT
(
    SUM(rsvCnt) for [yao] in ([1],[2],[3],[4],[5],[6],[7])
) TBL
where zhou=datepart(wk,'2023-04-17') and org is not null
and ([20230405]	is not null)






SELECT org,[20230403],[20230404],[20230405]
FROM [HerPeisTJTLTJZX].[dbo].[viDd]

PIVOT
(
    SUM(rsvCnt) for [ddStr] in ([20230403],[20230404],[20230405])--select dd from [HerPeisTJTLTJZX].[dbo].[viDd] WHERE	yy ='2023' and mm ='4' )
) TBL
where org is not null
and ([20230405]	is not null)


set datefirst 1

select datepart(weekday, getdate())

select datepart(dd, getdate())

PIVOT函数

    将商品类型列中的值转换为列标题

    SELECT 商店名,[短袖],[裤子]
    FROM 销售
    PIVOT(SUM(销售量) FOR 商品类型 IN ([短袖],[裤子])) a

    商店名   短袖    裤子
    安踏        20    56
    李宁        30    60
    安踏        61    60
    李宁        40    80
    安踏        55    78
    李宁        50    90

 明明SELECT语句中有商店名,怎么没有对商店名进行分组,为什么安踏和李宁出现三次,安踏短袖的销售数量不显示总和136,是不是有点像仅仅进行了行列转换?

这实际上与SQL语句的执行顺序有关,销售表中包含四列,分别为商店名,商品类型,销售量和日期,上述语句执行步骤类似如下:

1. 首先,对非聚合列进行分组,然后对聚合列进行统计

商店名,商品类型,销售日期为非聚合列,销售量为聚合列,商品类型既是非聚合列也是要成为列标题的列

SELECT 商店名,商品类型,销售日期,SUM(销售量)  FROM 销售 GROUP BY 商店名,商品类型, 销售日期

2.其次,将要成为列标题的值转化为透视列,值为聚合函数对应的值

具体为将商品类型列中的值转换为列标题,值为SUM(销售量)对应的值

3. 最后,从这个表中筛选出列

上述语句相当于筛选出商店名,短袖和裤子这三列

    SELECT 商店名,日期,[短袖],[裤子]
    FROM 销售
    PIVOT(SUM(销售量) FOR 商品类型 IN ([短袖],[裤子])) a

    商店名    日期    短袖    裤子
    安踏    2021-04-27    20    56
    李宁    2021-04-27    30    60
    安踏    2021-04-28    61    60
    李宁    2021-04-28    40    80
    安踏    2021-04-29    55    78
    李宁    2021-04-29    50    90

SELECT 商店名,[短袖],[裤子] FROM 销售 PIVOT(SUM(销售量) FOR 商品类型 IN ([短袖],[裤子])) a 和 SELECT 商店名,日期,[短袖],[裤子] FROM 销售 PIVOT(SUM(销售量) FOR 商品类型 IN ([短袖],[裤子])) a本质上是一样的,只是最后筛选出的列不同,换句话说PIVOT函数会对源表中除聚合列以外的所有列进行分组GROUP BY,即使SELECT语句中没有出现一些非聚合列

为了实现这段时间内各个商店各商品类型销售总额,需要在源表上进行调整

    统计这段时间内各个商店各商品类型销售总额,并将商品类型列中的值转换为列标题

    SELECT 商店名,[短袖],[裤子]
    FROM (SELECT 商店名,商品类型,销售量 FROM 销售) b
    PIVOT(SUM(销售量) FOR 商品类型 IN ([短袖],[裤子])) a

    商店名    短袖    裤子
    安踏       136     194
    李宁       120     230

综上,无论是利用CASE还是PIVOT进行透视功能,需要搞清楚是仅仅要实现行列转换,还是需要分组统计后再进行行列转换,不同的需求SQL语句会有差异,另外,对同一需求CASE和PIVOT的思路也是存在差异的
 

SQL SERVER PIVOT操作

 
 

PIVOT和UNPIVOT

PIVOT 通过将表达式中的一个列的唯一值转换为输出中的多列(即行转列),来轮替表值表达式。PIVOT 在需要对最终输出所需的所有剩余列值执行聚合时运行聚合。与 PIVOT 执行的操作相反,UNPIVOT 将表值表达式的列轮换为行(即列转行)。

但是需要注意得是,UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 执行聚合,并将多个可能的行合并为输出中的一行。UNPIVOT 不重现原始表值表达式的结果,因为行已被合并。

-- PIVOT 语法
SELECT <非透视的列>,
    [第一个透视的列] AS <列名称>,
    [第二个透视的列] AS <列名称>,
    ...
    [最后一个透视的列] AS <列名称>,

FROM
    (<生成数据的 SELECT 查询>) 
    AS <源查询的别名>

PIVOT
(
    <聚合函数>(<要聚合的列>)
FOR

[<包含要成为列标题的值的列>]
    IN ( [第一个透视的列], [第二个透视的列],
    ... [最后一个透视的列])
) AS <透视表的别名>
<可选的 ORDER BY 子句>;
展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部