新足迹

 找回密码
 注册

精华好帖回顾

· 也谈中文学校 (2009-7-1) 369 · I can't see myself... (2007-1-17) Kingfisher
· 吾心安处是故乡(一,二) (2005-11-20) 单衣纵酒 · 悉尼穷人买房记(更新完毕,并添片片了) (2009-11-29) 天涯浪客
Advertisement
Advertisement
查看: 4400|回复: 9

小虾米SQL的一个query求指点 [复制链接]

发表于 2015-7-27 20:40 |显示全部楼层
此文章由 Leaveland 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Leaveland 所有!转贴必须注明作者、出处和本声明,并保持内容完整
今天小虾米想写一个存储过程完成一项功能的时候
有一个看起来简单但实际上挠了一下午头也没想出来怎么做好

比如一个record表
Field A是integer可能是任何整数 其他Field都是字符串

FieldA  FieldB  FieldC
3           John  Smith
2           Lily    Smith

想要实现的是 run一个SP 对每一条记录检查FieldA的值 如果值n大于1 则复制该记录n次同时把FieldA的值从n一直排列到1

比如上面那个表最终update成这样

FieldA  FieldB  FieldC
3           John  Smith
2           John  Smith
1           John  Smith
2           Lily    Smith
1           Lily    Smith

是不是把复制的记录都select到一个临时表去然后再合并呢?

query复杂程度系统花销当然越低越好
IT版高人多 还望能指点迷津 先谢谢了!
Advertisement
Advertisement

发表于 2015-7-28 10:00 |显示全部楼层
此文章由 yolandalinz 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 yolandalinz 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我怎么看着像一个小程序应该干的事。。。有跟多需要理清,比如表里面有没有Duplicate Item,如果碰到应该怎么处理?

发表于 2015-7-28 18:44 |显示全部楼层
此文章由 qyz225 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 qyz225 所有!转贴必须注明作者、出处和本声明,并保持内容完整
本帖最后由 qyz225 于 2015-7-28 18:46 编辑

is it what you need? TSql recursive cte:


tsql recursive cte


use staging

declare @t table (FieldA int, FieldB varchar(50), FieldC varchar(50))

insert into @t
values
(3, 'John', 'Smith'),
(2, 'John', 'Smith'),
(2, 'Jack', 'London')

; with t1 as
(
select t.fielda, t.fieldb, t.fieldc, row_number() over (partition by fieldb, fieldc order by fielda) as ord
from @t t
)
, t2 as
(
select fielda, fieldb, fieldc
from t1
where ord = 1
union all
select fielda-1, fieldb, fieldc
from t2
where fielda > 1
)

select * from t2
union all
select fielda, fieldb, fieldc
from t1
where ord > 1
order by fieldb, fieldc, fielda desc


it is faster than while loop, but it could still be very slow if the table is too large, so it really depends on your business case...

评分

参与人数 2积分 +9 收起 理由
Leaveland + 4 你太有才了
melmonash + 5 你太有才了

查看全部评分

退役斑竹

发表于 2015-7-28 18:49 |显示全部楼层
此文章由 月亮 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 月亮 所有!转贴必须注明作者、出处和本声明,并保持内容完整
有很多方法做,但如果考虑最优的方法,Record表的大小直接影响用什么方法做

评分

参与人数 1积分 +4 收起 理由
Leaveland + 4 感谢分享

查看全部评分

发表于 2015-7-28 20:19 |显示全部楼层
此文章由 Leaveland 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Leaveland 所有!转贴必须注明作者、出处和本声明,并保持内容完整
qyz225 发表于 2015-7-28 18:44
is it what you need? TSql recursive cte:

太有才了

我也是想尽量避免loop
看起来不错

我明天实测一下看看效率

发表于 2015-7-28 20:21 |显示全部楼层
此文章由 Leaveland 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Leaveland 所有!转贴必须注明作者、出处和本声明,并保持内容完整
月亮 发表于 2015-7-28 18:49
有很多方法做,但如果考虑最优的方法,Record表的大小直接影响用什么方法做 ...

咋说呢

Record表的大小可能变化会非常大

跑SP之前也许只有几千条记录
但是那个int项的值 存在理论可能性会很大
所以表可能会膨胀得很厉害
Advertisement
Advertisement

发表于 2015-7-28 23:58 |显示全部楼层
此文章由 Fernando 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Fernando 所有!转贴必须注明作者、出处和本声明,并保持内容完整
表的基本情况,主键,索引,row cnt,读写状况,没有说
应用场景也要说清楚
很多时候loop就loop,膨胀就膨胀,效率低一点没太大关系。首先你要先定义好你需要的返回时间
like hell

发表于 2015-7-29 20:50 |显示全部楼层
此文章由 wonderdream 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 wonderdream 所有!转贴必须注明作者、出处和本声明,并保持内容完整
有一种东西叫 Tally table:

--Declare TestTable Variable
declare @t table (FieldA int, FieldB varchar(50), FieldC varchar(50))
insert into @t
values
(3, 'John', 'Smith'),
(2, 'John', 'Smith'),
(2, 'Jack', 'London')

--Genera Tally table (for SQL 2008+)
;WITH Tally (n) AS
(
    -- 1000 rows (10 x 10 x 10)
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) a(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(n)
    CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(n)
)
SELECT
        --t.FieldA,
        l.n,
        t.FieldB,
        t.FieldC
FROM @t t
        LEFT JOIN Tally l ON t.FieldA>=l.n
--ORDER by t.FieldA, t.FieldB, t.FieldC, l.n desc /* uncomment order clause in dev only */


T-SQL用set based operation是最快的。在使用loop和cte之前,先想想能不能用set based operation实现。

顺带一提,我公司招Senior Microsoft BI Developer, SSAS Tabular, SSIS, SSRS, Spark on HDInsight, Azure IaaS, PaaS, Power Shell. 如有兴趣,发我邮件: george.qiao@staples.com.au

评分

参与人数 2积分 +5 收起 理由
gzrain + 3 你太有才了
qyz225 + 2 感谢分享

查看全部评分

a

发表于 2015-7-29 21:12 |显示全部楼层
此文章由 浮云马 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 浮云马 所有!转贴必须注明作者、出处和本声明,并保持内容完整
好多高人。。。膜拜

发表于 2015-7-30 09:58 |显示全部楼层
此文章由 stevenbian 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 stevenbian 所有!转贴必须注明作者、出处和本声明,并保持内容完整
google sql server select 1 to n
最简单不用循环的貌似是找个大表抓行数

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部