SQL多表联查、自定义函数(字符串分割split)、xml格式输出

devtools/2025/1/13 10:30:50/

 记录一个报表的统计,大概内容如下:

多表联查涉及的报表有:房间表、买家表、合同表、交易表、费用表、修改记录表

注意:本项目数据库使用的是sqlserver(mssql),非mysql

难点1:业主信息( 身份证号)存在合同表中,需要通过“;”分割后,把相的联系方式或通讯地址合并显示在一个字段里;

1、创建split函数

--说明:
ALTER function  [dbo].[fn_Split](  
 @String nvarchar (max),  
 @Delimiter nvarchar (10)  
)  
RETURNS @ValueTable TABLE ([Value] NVARCHAR(4000),[id] int)  
BEGIN  
 DECLARE @NextString nvarchar(max),  
  @Pos int,  
  @NextPos int,  
  @CommaCheck nvarchar(1),
    @id int

set @id=1  
   
 SET @NextString = ''  
 SET @CommaCheck = right(@String,1)   
   
 SET  @String = @String + @Delimiter  
   
  SET @Pos = CHARINDEX(@Delimiter,@String)  
  SET @NextPos = 1  
   
 WHILE (@pos <>  0)    
 BEGIN  
  SET @NextString = SUBSTRING(@String,1,@Pos - 1)  
    
  INSERT INTO @ValueTable ( [Value],[id]) VALUES (@NextString,@id)  
    
  SET @String = SUBSTRING(@String,@pos +1,LEN(@String))  
     
  SET @NextPos = @Pos  
  SET @pos  = CHARINDEX(@Delimiter,@String)  

    set @id = @id +1
 END  
   
 RETURN  
END

 该函数返回的对象是table,值是value和id。 

 2、调用split函数

SELECT * FROM dbo.fn_Split('441900197605163536;513821199002186427', ';')

运行效果如下: 

调用函数时要注意使用方法,不是select dbo.split(),而是select * from dbo.split()

3、实际运用

把合同表中的身份证号分割出来,多表查询,重复的手机号做重复排查

 SELECT DISTINCT Tel+';' FROM dbo.fn_Split('身份证号1;身份证号2',';') b LEFT JOIN s_Buyer a ON a.CardID=b.value for xml path('')

 这样就能实现符号分割字符串,再通过for xml path('')把查询结果合并。

难点2:房间可能存在多次认购、取消认购、签署等业务状态,要把该房间的所有状态全部取出来放在一个备注字段;

 使用for xml path('')把查询结果合并输出来

详见下面博文:

https://blog.csdn.net/qqqqqwerttwtwe/article/details/144020795

难点3:多表联查(涉及到6个表格)

1、根据实际的业务逻辑,通过左连接(leftjoin)或内连接(innerjoin)查询

2、注意连接条件的唯一性,避免数据重复!

比如RoomGUID是唯一的(一个房间一个);

但是房子可能有多个合同,每个合同存在多个交易记录;

因此必须要考虑好统计的维度,避免数据重复。

以下是报表的完成SQL代码

SELECT
r.RoomInfo
,CONVERT(VARCHAR(100), t.RGOrderQsDate, 23) AS 认购日期
,c.CstAllName
,c.CstAllCardID
,联系方式=(SELECT DISTINCT Tel+';' FROM dbo.fn_Split(c.CstAllCardID,';') b LEFT JOIN s_Buyer a ON a.CardID=b.value for xml path(''))
,通讯地址=(SELECT DISTINCT Address+';' FROM dbo.fn_Split(c.CstAllCardID,';') b LEFT JOIN s_Buyer a ON a.CardID=b.value for xml path(''))
,c.payformname
,r.BldArea AS 建筑面积
,r.Total AS [成交总价]
,已收房款=(SELECT SUM(Amount) FROM s_Fee WHERE TradeGUID=t.TradeGUID)
,c.discntremark
,c.DiscntValueText
,CONVERT(VARCHAR(100), c.qsdate, 23) AS 签署日期
,c.agreementno
,c.ajbank
,c.ajtotal
,c.ajyear
,c.zygw
,bz=(select  CONVERT(VARCHAR(100), old.ApplyDate, 23)+''+ old.ApplyType +';'from s_SaleModiApply  oldwhere RoomGUID=r.RoomGUIDfor xml  path(''))
,r.Status
FROM s_Room r LEFT JOIN s_Trade t ON r.RoomGUID=t.RoomGUID
LEFT JOIN s_Contract c ON c.RoomGUID=r.RoomGUID AND c.ContractGUID=t.ContractGUID
WHERE r.Status in ('认购','签约') AND t.TradeStatus='激活'

http://www.ppmy.cn/devtools/150129.html

相关文章

性能优化案例:通过增加 shuffle 分区的数量来解决 PySpark 中的数据倾斜

在 PySpark 应用程序中&#xff0c;在随机操作期间&#xff0c;您可能会遇到由于数据倾斜而导致的性能下降&#xff0c;其中分区之间的数据分布不均匀可能会导致某些节点的处理时间比其他节点长得多。这可能会显著影响作业的执行时间&#xff0c;尤其是当数据集很大或某些键的数…

30天开发操作系统 第 12 天 -- 定时器 v1.0

前言 定时器(Timer)对于操作系统非常重要。它在原理上却很简单&#xff0c;只是每隔一段时间(比如0.01秒)就发送一个中断信号给CPU。幸亏有了定时器&#xff0c;CPU才不用辛苦地去计量时间。……如果没有定时器会怎么样呢?让我们想象一下吧。 假如CPU看不到定时器而仍想计量时…

cmake - build MS STL project

文章目录 cmake - build MS STL project概述笔记END cmake - build MS STL project 概述 MS在github上开源了VS IDE 用的STL实现。 想看看微软的测试用例中怎么用STL. 想先用CMake编译一个MS STL发布版出来。 笔记 CMake需要3.30以上, 拟采用 cmake-3.30.6-windows-x86_64.…

基于spingboot+html技术的博客网站

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

冒泡排序基础与实现

目录 1. 原理图 ​编辑 2. 什么是冒泡排序 3. 工作原理 3.1 具体步骤 3.2 时间复杂度 3.3 空间复杂度 4. 代码实现 5. 总结 1. 原理图 2. 什么是冒泡排序 冒泡排序&#xff08;Bubble Sort&#xff09;是一种简单的排序算法&#xff0c;它通过重复地遍历要排序的列表&am…

vue elementui 大文件进度条下载

下载进度条 <el-card class"box-card" v-if"downloadProgress > 0"><div>正在下载文件...</div><el-progress :text-inside"true" :stroke-width"26" :percentage"downloadProgress" status"…

51单片机——定时器中断(重点)

STC89C5X含有3个定时器&#xff1a;定时器0、定时器1、定时器2 注意&#xff1a;51系列单片机一定有基本的2个定时器&#xff08;定时器0和定时器1&#xff09;&#xff0c;但不全有3个中断&#xff0c;需要查看芯片手册&#xff0c;通常我们使用的是基本的2个定时器&#xff…

ubuntu设置开机无需输入密码自启动todesk,内网穿透natapp

设置todesk自启动 1、完善rc-local.service服务 sudo vim /lib/systemd/system/rc-local.service 写入以下内容 # SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modif…