关于SQL Server中STUFF的用法和基本优化

是在工作中有一个需求如下:
           在已经查出的数据A表中插入一个字段结果 统计B表中的某个字段并且用逗号隔开。
例如这个sql:
 

SELECT *,
       STUFF((select CASE
                         WHEN JH_HWZF_ZFD.CYFPH IS NOT NULL AND JH_HWZF_ZFD.CYFPH != ''
                             THEN ', ' + JH_HWZF_ZFD.CYFPH
                         ELSE '' end
              FROM  JH_HWZF_ZFD
              WHERE JH_HWZF_ZFD.PIH = MX.PIH
              FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '') AS CYFPH
FROM JH_HWZF_DZD AS DZD WITH (NOLOCK)
         LEFT JOIN JH_HWZF_DZDMX AS MX WITH (NOLOCK) ON DZD.DZDH = MX.DZDH AND MX.SCBJ = 0
         left join JH_HWZF_SQD as SQD with (nolock) on MX.FKSQDH = SQD.SQDH and sqd.SCBJ = 0
WHERE DZD.SCBJ = 0

这里使用的STUFF函数将查询结果使用逗号隔开,具体STUFF函数可以找其他文章看一下使用方法。
但是这里的子查询是写在SELECT语句中的,数据量越大,查询次数越多,速度越慢,实际测试数据在不到三千条的时候,就已经需要六十多秒的时间才能查完;

优化后可以声明一个临时变量表,使STUFF中的查询到临时变量表中去查,这样速度会提升非常快。

声明一个变量表 @zfd 里面是表的字段和类型

   DECLARE @zfd TABLE
        (
        PIH    VARCHAR(255),
        FPZDBH VARCHAR(255),
        CGS    VARCHAR(255),
        FPRZRQ date,
        CYFS   VARCHAR(255),
        CYFPH  VARCHAR(255),
        HWDCRQ date,
        HWRKDH VARCHAR(255)
        );

这里是将临时要用到的数据查询出来 赋值给上方的临时变量表,这个尽量缩小表的范围和大小
 


        INSERT INTO @zfd
        SELECT PIH, FPZDBH, CGS, FPRZRQ, CYFS, CYFPH, HWDCRQ,HWRKDH
        FROM JH_HWZF_ZFDMX with (nolock)
        right join JH_HWZF_ZFD with (nolock) on JH_HWZF_ZFDMX.ZFDH = JH_HWZF_ZFD.ZFDH
        WHERE JH_HWZF_ZFD.SCBJ = 0
        and JH_HWZF_ZFDMX.SCBJ = 0
        and PIH in (

            SELECT
        mx.PIH
        FROM JH_HWZF_DZD AS DZD WITH (NOLOCK)
        LEFT JOIN JH_HWZF_DZDMX AS MX WITH (NOLOCK) ON DZD.DZDH = MX.DZDH AND MX.SCBJ = 0
        left join JH_HWZF_SQD as SQD with (nolock) on MX.FKSQDH = SQD.SQDH and sqd.SCBJ = 0
        WHERE DZD.SCBJ = 0

 下面的子查询中,需要取得数据从临时变量表中取值即可,实测目前查询是一秒多

SELECT *,
       STUFF((select CASE
                         WHEN JH_HWZF_ZFD.CYFPH IS NOT NULL AND JH_HWZF_ZFD.CYFPH != ''
                             THEN ', ' + JH_HWZF_ZFD.CYFPH
                         ELSE '' end
              FROM @zfd as JH_HWZF_ZFD
              WHERE JH_HWZF_ZFD.PIH = MX.PIH
              FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '') AS CYFPH
FROM JH_HWZF_DZD AS DZD WITH (NOLOCK)
         LEFT JOIN JH_HWZF_DZDMX AS MX WITH (NOLOCK) ON DZD.DZDH = MX.DZDH AND MX.SCBJ = 0
         left join JH_HWZF_SQD as SQD with (nolock) on MX.FKSQDH = SQD.SQDH and sqd.SCBJ = 0
WHERE DZD.SCBJ = 0

下面是完整的sql

不需要分开写  完整的执行就行

DECLARE @zfd TABLE
             (
                 PIH    VARCHAR(255),
                 FPZDBH VARCHAR(255),
                 CGS    VARCHAR(255),
                 FPRZRQ date,
                 CYFS   VARCHAR(255),
                 CYFPH  VARCHAR(255),
                 HWDCRQ date,
                 HWRKDH VARCHAR(255)
             );


INSERT INTO @zfd
SELECT PIH, FPZDBH, CGS, FPRZRQ, CYFS, CYFPH, HWDCRQ,HWRKDH
FROM JH_HWZF_ZFDMX with (nolock)
         right join JH_HWZF_ZFD with (nolock) on JH_HWZF_ZFDMX.ZFDH = JH_HWZF_ZFD.ZFDH
WHERE JH_HWZF_ZFD.SCBJ = 0
  and JH_HWZF_ZFDMX.SCBJ = 0;



SELECT *,
       STUFF((select CASE
                         WHEN JH_HWZF_ZFD.CYFPH IS NOT NULL AND JH_HWZF_ZFD.CYFPH != ''
                             THEN ', ' + JH_HWZF_ZFD.CYFPH
                         ELSE '' end
              FROM @zfd as JH_HWZF_ZFD
              WHERE JH_HWZF_ZFD.PIH = MX.PIH
              FOR XML PATH(''), TYPE).value('.[1]', 'nvarchar(max)'), 1, 2, '') AS CYFPH
FROM JH_HWZF_DZD AS DZD WITH (NOLOCK)
         LEFT JOIN JH_HWZF_DZDMX AS MX WITH (NOLOCK) ON DZD.DZDH = MX.DZDH AND MX.SCBJ = 0
         left join JH_HWZF_SQD as SQD with (nolock) on MX.FKSQDH = SQD.SQDH and sqd.SCBJ = 0
WHERE DZD.SCBJ = 0

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值