SQL Server中UNPIVOT的妙用

请添加图片描述

事情的起因

在这里插入图片描述
力扣传送门

题解

这个题目就两个点,1.人数大于100 2.id是连续的,且连续3次或者以上,所以难点就是你如何去判断出连续的3个id数据

我的解
WITH tre AS(
SELECT a.id AS aid,b.id AS bid,c.id AS cid FROM Stadium a LEFT JOIN Stadium b ON a.id+1=b.id
LEFT JOIN Stadium c ON b.id+1=c.id
WHERE a.id!=b.id and b.id!=c.id AND a.people>=100 AND b.people>=100 AND c.people>=100
)

SELECT * FROM Stadium WHERE id IN(
SELECT DISTINCT ccc.orders FROM tre
UNPIVOT(
	orders for emp IN(aid,bid,cid)
)AS ccc
)
ORDER BY visit_date
我的解注解

写的比较粗糙,命名啥的也不是很规范哈,大家别太扣细节,基本上就跟做草稿一样,我的思路是先联表2次,这样可以保障得到3个连续的id,比如1,2,3和2,3,4都是合理的,然后再去重把这些id拿出来,这样就可以得到连续的id了,这个过程唯一的问题点就是行转列,然后我第一时间就想到了UNPIVOT,把三个表的id修改成列,这样就可以得到所有的id了

最优解
SELECT *
FROM Stadium
WHERE id IN
(
    SELECT id
    FROM
    (
        SELECT id, COUNT(*) OVER (PARTITION BY Diff) AS Diff
        FROM
        (
            SELECT id, visit_date, people, id - RowNum AS Diff
            FROM
            (
                SELECT *
                    ,ROW_NUMBER() OVER (ORDER BY id) AS RowNum
                FROM Stadium
                WHERE people >= 100
            ) X
        ) X                                                                                                                                                                                                                                                                                                                                             
    ) X
    WHERE Diff >= 3
)
ORDER BY visit_date
最优解注解

咋一看好像挺麻烦的,循环包循环的感觉,但是他这个思路其实很明确,就是利用连续的id,制造一个差值的排序,如果他们是连续的,那么连续的id减去差值就会等于同一个值,以后大家去判断连续的id的时候,都可以利用这种方法,这就是一种套路,跟算法思维很像,很推崇这种思维,算法思维肯定是找相似性,我做sql算法,主要是强化sql语法,所以我会侧重去用语法去解决问题,而不是带着算法思维,去找问题的相似性,这个大家要区分一下,但是如果有算法思维,那会更好,在遇到一些共性问题的时候,可以用相同的解决方案

图解

在这里插入图片描述

  • 23
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
SQLUNPIVOT是一种操作,用于将列转换为行。它可以将多个列合并为一个列,并将其值作为新的行。UNPIVOT操作的语法如下所示: SELECT <non-pivoted column>, \[new column name\] FROM (原始数据 UNPIVOT (\[new column name\] FOR \[column name\] IN (\[value1\], \[value2\], ...)) AS \[alias\]) 其,\[non-pivoted column\]是不需要转换的列,\[new column name\]是新列的名称,\[column name\]是包含要转换的值的列的名称,\[value1\], \[value2\], ...是要转换的值。 例如,如果有一个名为#person的表,包含id和num两列,可以使用UNPIVOT操作将num列转换为新的列。具体的SQL语句如下所示: SELECT '身高' AS highs, \[1\], \[2\], \[3\], \[4\], \[5\] FROM (SELECT id, num FROM #person) s PIVOT (AVG(num) FOR id IN (\[1\], \[2\], \[3\], \[4\], \[5\])) AS p 这将生成一个新的表,其包含一个名为highs的列和以id为列头的新列,每个新列的值是num列的平均值。 #### 引用[.reference_title] - *1* [2022-03-10 SQL行转列语句unpivot使用笔记](https://blog.csdn.net/weixin_44190736/article/details/123394776)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [sql server行转列(pivot),列转行(unpivot)](https://blog.csdn.net/weixin_51803498/article/details/125195863)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值