原文:在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存)


最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了。

所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路。

求教:我有个表有入库时间,有出库时间,我想得到该样式号每月的销售和历史库存

http://bbs.csdn.net/topics/390629790

库结构大概是这样:

货号    样式号    入库时间    出库时间

a001    10    2011-1-10        

b002    10    2011-1-10    2011-2-1

c003    10    2012-1-15    2012-2-2

d004    10    2013-2-3    2013-1-5

e005    10    2013-2-3        

f006    15    2011-2-15    2011-3-16

g007    15    2011-2-16    2012-3-16

h009    15    2013-1-10    

m012    18    2011-1-4        

c009    18    2011-4-5    2012-5-6

f008    18    2012-2-19    2013-1-1

e008    18    2013-1-5    2013-2-6

 

我想得到的结果:

样式号    日期    销售件数    库存件数    

10    2011-2    1    1

10    2012-2    1    1

10    2013-1    1    2

15    2011-3    1    0

15    2012-3    1    1

18    2012-5    1    1

18    2013-1    1    1

18    2013-2    1    1

我的解法:


  1. if object_id('tb') is not null
  2. drop table tb
  3. go
  4. create table tb
  5. (
  6. [货号] varchar(20),[样式号] int,
  7. [入库时间] datetime,
  8. [出库时间] datetime
  9. )
  10. insert into tb
  11. SELECT 'a001',10,'2011-01-10',null UNION ALL
  12. SELECT 'b002',10,'2011-01-10','2011-02-01' UNION ALL
  13. SELECT 'c003',10,'2012-01-15','2012-02-02' UNION ALL
  14. SELECT 'd004',10,'2013-01-03','2013-01-05' UNION ALL
  15. SELECT 'e005',10,'2013-01-03',null UNION ALL
  16. SELECT 'f006',15,'2011-02-15','2011-03-16' UNION ALL
  17. SELECT 'g007',15,'2011-02-16','2012-03-16' UNION ALL
  18. SELECT 'h009',15,'2013-01-10',null UNION ALL
  19. SELECT 'm012',18,'2011-01-04',null UNION ALL
  20. SELECT 'c009',18,'2011-04-05','2012-05-06' UNION ALL
  21. SELECT 'f008',18,'2012-02-19','2013-01-01' UNION ALL
  22. SELECT 'e008',18,'2013-01-05','2013-02-06'
  23. go
  24. ;with t
  25. as(
  26. select *,
  27. row_number() over(partition by 样式号
  28. order by 入库时间,出库时间) as rownum
  29. from tb
  30. ),
  31. tt
  32. as
  33. (
  34. select *,
  35. case when 出库时间 is null
  36. then (select top 1 出库时间
  37. from t t2
  38. where t1.样式号 = t2.样式号 and
  39. t1.rownum > t2.rownum
  40. order by t2.rownum desc)
  41. else 出库时间
  42. end as prior_row,
  43. case when 出库时间 is null
  44. then (select top 1 出库时间
  45. from t t2
  46. where t1.样式号 = t2.样式号 and
  47. t1.rownum < t2.rownum
  48. order by t2.rownum )
  49. else 出库时间
  50. end as next_row
  51. from t t1
  52. ),
  53. ttt
  54. as
  55. (
  56. select 样式号,
  57. convert(varchar(7),isnull(next_row,prior_row),120) as 日期,
  58. count(出库时间) 销售件数,
  59. count(入库时间) 库存件数,
  60. count(入库时间) - count(出库时间) 剩余库存
  61. --row_number() over(partition by 样式号
  62. --order by convert(varchar(7),isnull(next_row,prior_row),120)) as rownum
  63. from tt
  64. group by 样式号,
  65. convert(varchar(7),isnull(next_row,prior_row),120)
  66. )
  67. select t1.样式号,t1.日期,
  68. isnull(t1.销售件数,0) as 销售件数 ,
  69. isnull(t1.库存件数,0) +
  70. isnull((select sum(库存件数)-sum(销售件数) as 剩余库存 from ttt t2
  71. where t2.样式号 = t1.样式号
  72. and t2.日期 < t1.日期
  73. ),0) -
  74. isnull(t1.销售件数,0) as 库存件数
  75. from ttt t1
  76. order by t1.样式号
  77. /*
  78. 样式号 日期 销售件数 库存件数
  79. 10 2011-02 1 1
  80. 10 2012-02 1 1
  81. 10 2013-01 1 2
  82. 15 2011-03 1 0
  83. 15 2012-03 1 1
  84. 18 2012-05 1 1
  85. 18 2013-01 1 1
  86. 18 2013-02 1 1
  87. */

发布了416 篇原创文章 · 获赞 135 · 访问量 95万+

在论坛中出现的比较难的sql问题:40(子查询 销售和历史库存)的更多相关文章

  1. 在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题)

    原文:在论坛中出现的比较难的sql问题:46(日期条件出现的奇怪问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有 ...

  2. 在论坛中出现的比较难的sql问题:45(用户在线登陆时间的小时、分钟计算问题)

    原文:在论坛中出现的比较难的sql问题:45(用户在线登陆时间的小时.分钟计算问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. ...

  3. 在论坛中出现的比较难的sql问题:44(触发器专题 明细表插入数据时调用主表对应的数据)

    原文:在论坛中出现的比较难的sql问题:44(触发器专题 明细表插入数据时调用主表对应的数据) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决 ...

  4. 在论坛中出现的比较难的sql问题:42(动态行转列 考勤时间动态列)

    原文:在论坛中出现的比较难的sql问题:42(动态行转列 考勤时间动态列) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  5. 在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字)

    原文:在论坛中出现的比较难的sql问题:41(循环替换 循环替换关键字) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  6. 在论坛中出现的比较难的sql问题:39(动态行转列 动态日期列问题)

    原文:在论坛中出现的比较难的sql问题:39(动态行转列 动态日期列问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉 ...

  7. 在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题)

    原文:在论坛中出现的比较难的sql问题:38(字符拆分 字符串检索问题) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得 ...

  8. 在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名)

    原文:在论坛中出现的比较难的sql问题:37(动态行转列 某一行数据转为列名) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

  9. 在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串)

    原文:在论坛中出现的比较难的sql问题:36(动态行转列 解析json格式字符串) 所以,觉得有必要记录下来,这样以后再次碰到这类问题,也能从中获取解答的思路.

随机推荐

  1. Java 什么是静态内部类

    #定义 Java语言允许在类中再定义类,这种在其它类内部定义的类就叫内部类. 有static关键字修饰的内部类. 比如:Pattern类中的Node类. public class Outer { pr ...

  2. js监听浏览器剪贴板

    function setClipboardText(event){ event.preventDefault(); var node = document.createElement('div'); ...

  3. Andorid SQLite数据库开发基础教程(2)

    Andorid SQLite数据库开发基础教程(2) 数据库生成方式 数据库的生成有两种方式,一种是使用数据库管理工具生成的数据库,我们将此类数据库称为预设数据库,另一种是使用代码生成的数据库.

  4. Maltego更新到4.2.4.12374

    Maltego更新到4.2.4.12374   这次更新修改多个bug,并增加一些的特性和功能.主要变化如下: (1)允许用户直接复制实例的属性,以粘贴方式创建新实体. (2)右击网址类实体,右键菜单 ...

  5. python制作简单excel统计报表1之with的简单用法

    # coding=utf-8 def open_file(): """使用with打开一个文件""" # 普通操作文件方法 # f = op ...

  6. 安卓终端-Termux

    Termux是一个 Android 终端模拟器以及提供 Linux 环境的应用程序.跟许多其他应用程序不同,无需 root 设备也无需进行设置.它是开箱即用的!它会自动安装好一个最基本的 Linux ...

  7. windows驱动程序中的预处理含义

    #pragma  code_seg(“PAGE”) 作用是将此部分代码放入分页内存中运行. #pragma  code_seg() 将代码段设置为默认的代码段 #pragma  code_seg(&q ...

  8. QML随机颜色

    color=Qt.rgba(Math.random(),Math.random(),Math.random(),1)

  9. LinkedHashMap和hashMap和TreeMap的区别

    推荐博客:https://www.jianshu.com/p/8f4f58b4b8ab 区别: LinkedHashMap是继承于HashMap,是基于HashMap和双向链表来实现的. HashMa ...

  10. NETTY option参数

    Channel配置参数 (1).通用参数 CONNECT_TIMEOUT_MILLIS :   Netty参数,连接超时毫秒数,默认值30000毫秒即30秒. MAX_MESSAGES_PER_REA ...