首页 新闻 会员 周边

一个关于SqlServer或程序实现卡号数字连续分组的问题

-1
悬赏园豆:50 [已解决问题] 解决于 2015-07-09 15:34

有个卡库存表,有个卡号字段,假设数据:16001,16002,16003,16008.16009,16010,16211,16212。注:实际的数据量会很大,卡
号会很长。 现在要这样用sql统计出来,或者用程序实现,卡段号:16001~16003 数量:3    卡段号:16008~16010 数量:3   
  卡段号:16211~16212 数量:2      暂时没想到什么好的解决办法,求各位大神支招,不一定要写出来,能提供思路也行。。
。谢谢

kungge的主页 kungge | 初学一级 | 园豆:132
提问于:2015-02-06 10:16
< >
分享
最佳答案
0

谢谢各位的回答,问题我已得到解决,我再次把需求简单描述下吧。

表库存表:卡名称、面额、卡号、状态等...

比如卡名称"上海珠宝卡"面额200的这个卡有很多,每个卡都有一个对应的卡号(比如向557105041502662,可能也有字母在卡号的前面),这些卡可能是一批卡,面额都一样的,假设有10000张,在数据库中一个卡号就是一条记录,但是客户不想看到列表中是一张张的卡,而是用卡号段统计出来的,比如557105041502662~557105041502761数量是100张。只要是卡号数字是连续的就组成一条记录显示卡号段和数量。

实际设计:表CardStock:CardId(卡种类)、IndetailId(入库单的Id)、CardNum(卡号)...

select CardId,IndetailId,
(case when sum(1)>1 then cast(MIN(CardNum) as varchar(32))+ '~'+ cast(MAX(CardNum) as varchar(32)) else cast(MIN(CardNum) as varchar(32)) end) AS CardNumSection,
sum(1) as CardCount,
 from(
SELECT CardId ,IndetailId ,CardNum,
CardNum - ROW_NUMBER() OVER(partition by CardId ,IndetailId ORDER BY CardNum) AS grp
 FROM CardStock) v

其中CardNumSection就是卡号段,若是一张就直接显示卡号就行

kungge | 初学一级 |园豆:132 | 2015-04-05 18:10
其他回答(7)
0

select Count(*) from table where 卡号 between 卡号1 and 卡号2

收获园豆:1
刘宏玺 | 园豆:14020 (专家六级) | 2015-02-06 10:21
0

思路1:将卡库存表导入reportservice数据库中,写SQL通过字符串函数分组查询统计,目测SQL会非常啰嗦,执行耗时很长,但不影响主库性能,且可以统计出结果

思路2:

新建一张卡号段统计表,然后分页批量查询卡库存,每次n条,查好后在内存中分组,最后插入或者更新卡号段统计表。因为你的业务逻辑要求必须全表查询,所以个人认为分页批量多次是较好的选择。

收获园豆:20
JeffWong | 园豆:2328 (老鸟四级) | 2015-02-06 10:24
0

需求描述不清晰,卡段号是按照什么逻辑分段的?

收获园豆:1
爱编程的大叔 | 园豆:30839 (高人七级) | 2015-02-06 12:16
0

将卡号字段数据处理为一个临时table,然后将条件处理为>=min and <=max,这样就能很容易求出数量了。。。对于这种,直接存储过程吧。。如果数据内存吃得住的话,直接查询出来,用Linq在内存中搞定。

收获园豆:5
幻天芒 | 园豆:37175 (高人七级) | 2015-02-06 13:19
0

这是老师给你出的算法题,还是你自己想出来的用来解决用户需求的解决方案?

收获园豆:2
Launcher | 园豆:45045 (高人七级) | 2015-02-06 13:25
0

卡端号有什么规律什么的?

收获园豆:1
子曰过 | 园豆:189 (初学一级) | 2015-02-06 13:51
0
WITH
    TAB AS (SELECT '16001111' CARD FROM DUAL UNION ALL
            SELECT '16001222' CARD FROM DUAL UNION ALL
            SELECT '16002111' CARD FROM DUAL UNION ALL
            SELECT '16003111' CARD FROM DUAL UNION ALL
            SELECT '16004111' CARD FROM DUAL UNION ALL
            SELECT '16005111' CARD FROM DUAL UNION ALL
            SELECT '16008111' CARD FROM DUAL)
SELECT 
   TO_CHAR(FLOOR((TO_NUMBER(SUBSTR(CARD, 1, 5)) + 1) / 3) * 3 - 1) || '~' ||
   TO_CHAR(FLOOR((TO_NUMBER(SUBSTR(CARD, 1, 5)) + 1) / 3) * 3 + 2), COUNT(1)
FROM TAB
GROUP BY FLOOR((TO_NUMBER(SUBSTR(CARD, 1, 5)) + 1) / 3)
ORDER BY FLOOR((TO_NUMBER(SUBSTR(CARD, 1, 5)) + 1) / 3)
收获园豆:20
过于执著 | 园豆:339 (菜鸟二级) | 2015-02-09 12:54

截取字符串, 转换成数字,

加 1, 以便 最小值能被 3整除,

按商分组

取结果时 把刚才的 加的 1 减去.

支持(0) 反对(0) 过于执著 | 园豆:339 (菜鸟二级) | 2015-02-09 12:57

我这儿没 Sql Service

对应的 TO_NUMBER, TO_CHAR 请自行转换成  CONVERT

对应的  || 请自行转换成 +

支持(0) 反对(0) 过于执著 | 园豆:339 (菜鸟二级) | 2015-02-09 13:00
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册