当前位置: 首页 > news >正文

sql server数据一对多合并_SQL Server 合并多对多表的数据

点击上方蓝字关注“汪宇杰博客”

fe44c6574c670c8254bb4583b41707c9.png

今天还是发一篇老文。介绍当时我合并博客文章数据时遇到的一个问题和解决方法。我不擅长SQL,如果大家有更好的方法,欢迎在评论里留言讨论。

最近在整理博客的数据,需要做一个操作就是合并文章的分类。我的博客中文章和分类是多对多的关系。即一篇文章可以属于多个分类,一个分类可以包含多篇文章。这是一个很典型的多对多关系,我用的是一个多对多的表,做联合主键关联这些数据。

就像这样:

cad75e65b4658ceb089392b9eac3ca69.png 35d86218cf887e8792b74a33db05d8b6.png

我需要做的是把“DotNetBeginner”这个分类的文章移到“CSharpAndDotNet”分类里去。但是因为原先在“DotNetBeginner”里的文章有些也是属于“CSharpAndDotNet”的,所以直接Update关联表的话,会产生重复的联合主键,就会爆

直观一点看,写个SQL语句查询出原分类(DotNetBeginner)和目标分类(CSharpAndDotNet)中的数据:

DECLARE @SourceCatId     AS UNIQUEIDENTIFIER,

        @TargetCatId     AS UNIQUEIDENTIFIER

SET @SourceCatId = '678A4011-40E0-4F75-BC23-1FFC25B72D4A'

SET @TargetCatId = 'D58043FF-B3CB-43DA-9067-522D76D21BE3'

SELECT p.Title,

       c.Name

FROM   PostCategory         AS pc

       INNER JOIN Post      AS p

            ON  p.Id = pc.PostId

       INNER JOIN Category  AS c

            ON  c.Id = pc.CategoryId

WHERE  pc.CategoryId IN (@SourceCatId, @TargetCatId)

结果如下图:

《C#字符和ASCII码互转》这篇如果直接update分类到CSharpAndDotNet就会爆,因为PostCategory表中已经有一条这样的记录了。但是像《上海轨道交通……》那篇就可以直接update。

2083d4c43705327756b0c312a168f1d4.png

解决这个问题的思路分两步:

1. 删除如《C#字符和ASCII码互转》这种的会爆破联合主键的记录

2. 更新关联表,把旧分类的ID改成新分类

那么首先我们要知道有哪些记录是符合被删除的条件的,把这些文章的ID找出来,用一个group by having就可以爆出来:

SELECT pc.PostId

FROM   PostCategory AS pc

WHERE  pc.CategoryId IN (@SourceCatId, @TargetCatId)

GROUP BY

       pc.PostId

HAVING COUNT(*) >= 2

结果有10条:

2d34470b7a8e43c2fbbcc13f7d5c3af6.png

这10篇文章同时属于DotNetBeginnerCSharpAndDotNet和其他分类。

为了直观的显示和之后删除操作方便,定义一个表变量叫temp,然后验证一下是哪些文章:

DECLARE @Temp TABLE (PostId UNIQUEIDENTIFIER)

INSERT INTO @Temp

  (

    PostId

  )(

       SELECT pc.PostId

       FROM   PostCategory AS pc

       WHERE  pc.CategoryId IN (@SourceCatId, @TargetCatId)

       GROUP BY

              pc.PostId

       HAVING COUNT(*) >= 2

   )

------------------------------------------------------------------------------

SELECT --pc.PostId

       p.Title,

       --pc.CategoryId,

       c.Name

FROM   PostCategory         AS pc

       INNER JOIN Post      AS p

            ON  p.Id = pc.PostId

       INNER JOIN Category  AS c

            ON  c.Id = pc.CategoryId

WHERE  pc.PostId IN (SELECT t.PostId

                     FROM   @Temp t)

发现结果是正确的:

e7d88ba7c49039cbc7b21a4f0371434f.png

然后就可以从关联表PostCategory中删除所有文章ID(PostId)在@Temp表中,且CategoryId对应DotNetBeginner的记录。然后用update语句完成文章分类的合并。

-- Step 1. Delete records that will fuck up the primary key

DELETE 

FROM   PostCategory

WHERE  CategoryId = @SourceCatId

       AND PostId IN (SELECT t.PostId

                      FROM   @Temp t)

-- Step 2. Update old key to new key

UPDATE PostCategory

SET    CategoryId     = @TargetCatId

WHERE  CategoryId     = @SourceCatId

最后验证一下,数据已经成功合并了。

ac2f230e861a6f70acb0a2ef0e3916b4.png

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 设备ip搜索工具_网销侠:网络营销百问百答之49,常用的网站统计工具有哪些...
  • c语言源代码_学好C语言的这7个步骤,你都了解吗?
  • excel部分字段相同模糊匹配_你-早该这么玩 Excel
  • vue按需加载组件_require.ensure实现webpack按需加载
  • networkx 标签_NetworkX:是一个简单、多样化、能快速生成网络图形的Python库
  • 华为三层交换机配置步骤_华为交换机Trunk配置
  • python 遍历所有文件夹和子文件夹_Python 遍历子文件和所有子文件夹的代码实例...
  • redis模糊查询key前缀_Redis内存数据监控实战
  • completablefuture 线程池_线程池ForkJoinPool简介
  • 判断多个数据是否是两个素数相乘_循环结构程序举例2素数的判断
  • chrome 验证码识别 扩展_chrome插件市场国内无法打开,我来教你如何安装插件
  • python深度神经网络_PyTorch进阶:深度神经网络中的前馈过程(图解分析)
  • python判断能否组成三角形_如何用PYTHON判断三角形的类型 需要技巧
  • 查看python安装成功的命令_Python sqlite3模块 安装查询命令等使用讲解
  • python输入半径计算公式_python练习:取输入半径的周长和面积
  • Apache Zeppelin在Apache Trafodion上的可视化
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Flannel解读
  • gcc介绍及安装
  • leetcode98. Validate Binary Search Tree
  • ReactNativeweexDeviceOne对比
  • SAP云平台里Global Account和Sub Account的关系
  • vue中实现单选
  • WordPress 获取当前文章下的所有附件/获取指定ID文章的附件(图片、文件、视频)...
  • 翻译--Thinking in React
  • 给第三方使用接口的 URL 签名实现
  • 漂亮刷新控件-iOS
  • 前端存储 - localStorage
  • 嵌入式文件系统
  • 三栏布局总结
  • 一个完整Java Web项目背后的密码
  • ​比特币大跌的 2 个原因
  • ​如何防止网络攻击?
  • ​字​节​一​面​
  • # 详解 JS 中的事件循环、宏/微任务、Primise对象、定时器函数,以及其在工作中的应用和注意事项
  • $(function(){})与(function($){....})(jQuery)的区别
  • (16)Reactor的测试——响应式Spring的道法术器
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (cljs/run-at (JSVM. :browser) 搭建刚好可用的开发环境!)
  • (Demo分享)利用原生JavaScript-随机数-实现做一个烟花案例
  • (poj1.3.2)1791(构造法模拟)
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (附源码)spring boot北京冬奥会志愿者报名系统 毕业设计 150947
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot工单管理系统 毕业设计 964158
  • (七)Flink Watermark
  • (原創) 物件導向與老子思想 (OO)
  • (原創) 系統分析和系統設計有什麼差別? (OO)
  • (转)IOS中获取各种文件的目录路径的方法
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .net core使用EPPlus设置Excel的页眉和页脚
  • .NET 给NuGet包添加Readme
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .pings勒索病毒的威胁:如何应对.pings勒索病毒的突袭?
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录