当前位置:   article > 正文

数据库的存储过程设计(1)_数据库存储过程设计

数据库存储过程设计


需求:

统计一个sql server表单中的故障数据,根据故障类型和故障等级及故障次数,统计出一段时间内的故障积分,要总分,及前三的故障分和故障类型。


Step1:

因为对db不太熟悉,并且觉得视图比较直观,可以看到中间结果,所以,第一步做的先是统计出相关故障和次数。这涉及到故障信息表,设备的信息表,故障的配置表,以及设备所在项目的配置表。因为故障配置和项目配置都有静默时间,在这段静默时间里的故障是不作数的,所以要剔除出去。

视图1 by_v_etor_fault_score

  1. SELECT
  2. a.id,
  3. a.etor_id,
  4. a.dtu_bianhao,
  5. a.master_code,
  6. a.create_time,
  7. b.bianhao AS etor_bianhao,
  8. b.dtu_id,
  9. b.etor_species_id,
  10. b.project_id,
  11. b.organize_id,
  12. b.dizhi_code,
  13. b.build_name,
  14. b.build_number,
  15. b.build_etorindex,
  16. b.dizhi_detail,
  17. b.zuobiao,
  18. b.zhuban_code,
  19. b.zhuban_version,
  20. b.zhuban_version_time,
  21. b.floorcount,
  22. b.weibao_user,
  23. b.weibao_userphone,
  24. b.weibao_manager,
  25. b.weibao_managerphone,
  26. b.weibao_interval,
  27. b.weibao_type,
  28. b.nianjian_time,
  29. b.use_place,
  30. b.brand_id,
  31. b.etor_model,
  32. b.product_model,
  33. c.fault_code,
  34. c.fault_display_code,
  35. c.fault_desc,
  36. c.is_alarm,
  37. c.levels,
  38. c.sleep_starttime,
  39. c.sleep_endtime,
  40. d.caption AS etor_species_caption,
  41. d.code AS etor_species_code,
  42. d.etor_type,
  43. d.remote_aspx,
  44. d.etor_default_img,
  45. d.mask_format,
  46. table_proj.sleep_starttime AS proj_sleep_starttime,
  47. table_proj.sleep_endtime AS proj_sleep_endtime
  48. FROM
  49. dbo.by_etor_tickets_fault AS a
  50. INNER JOIN dbo.by_etor AS b ON a.etor_id = b.id
  51. INNER JOIN dbo.by_etor_fault_config AS c ON a.master_code = c.fault_code AND b.etor_species_id = c.etor_species_id
  52. INNER JOIN dbo.by_etor_species AS d ON b.etor_species_id = d.id
  53. INNER JOIN dbo.by_project AS table_proj ON b.project_id = table_proj.id
  54. --filter sleep time
  55. where
  56. (
  57. ( ISNULL(table_proj.sleep_starttime, '') = '' or ISNULL(table_proj.sleep_endtime, '') ='' )
  58. OR
  59. ( ISNULL(table_proj.sleep_starttime, '') != '' and ISNULL(table_proj.sleep_endtime, '') != ''
  60. AND
  61. (
  62. (convert(datetime,table_proj.sleep_starttime) < convert(datetime,table_proj.sleep_endtime)
  63. AND convert(varchar(8),a.create_time,108) not between convert(datetime,table_proj.sleep_starttime) AND convert(datetime,table_proj.sleep_endtime)
  64. )
  65. OR
  66. (convert(datetime,table_proj.sleep_starttime) > convert(datetime,table_proj.sleep_endtime)
  67. AND (convert(varchar(8),a.create_time,108) between convert(datetime,table_proj.sleep_endtime) AND convert(datetime,table_proj.sleep_starttime))
  68. )
  69. )
  70. )
  71. )
  72. AND
  73. (
  74. ( ISNULL(c.sleep_starttime, '') = '' or ISNULL(c.sleep_endtime, '') ='' )
  75. OR
  76. ( ISNULL(c.sleep_starttime, '') != '' and ISNULL(c.sleep_endtime, '') != ''
  77. AND
  78. (
  79. (convert(datetime,c.sleep_starttime) < convert(datetime,c.sleep_endtime)
  80. AND convert(varchar(8),a.create_time,108) not between convert(datetime,c.sleep_starttime) AND convert(datetime,c.sleep_endtime)
  81. )
  82. OR
  83. (convert(datetime,c.sleep_starttime) > convert(datetime,c.sleep_endtime)
  84. AND (convert(varchar(8),a.create_time,108) between convert(datetime,c.sleep_endtime) AND convert(datetime,c.sleep_starttime))
  85. )
  86. )
  87. )
  88. )
  89. --end where ---

其结果如下








整合了4张表,类型比较多,或可筛选,当着不是我们当前关注的东西。


我们主要在于故障项。master_code栏是故障码,对应fault_code是一致的。由于一个设备可能会多次出现相同故障,以及根据levels划分的故障级别有不同的记分等级。所以基于上面我们有了第二个视图。


Step2:

对上个视图进行筛选,暂定于名称为:by_v_etor_fault_score_top3,因为我们最后在意的是前3个高分。

其中etor_id<100是只取前100个,只为在调试阶段减少数据量。

  1. SELECT etor_id,fault_code,fault_desc,
  2. sum( case when levels=0 then 20
  3. when levels=1 then 10
  4. when levels=2 then 6
  5. when levels=3 then 4
  6. when levels=4 then 2
  7. when levels=5 then 1 --0.1~1
  8. else 0 end) as fault_score
  9. from by_v_etor_fault_score
  10. where etor_id<100
  11. GROUP BY etor_id,fault_code,fault_desc
其结果为,这儿并没有取前3,因为还要统计一个总分,但这个筛选语句明显少了,case when是故障等级相应的积分。



Step3:

针对上张表统计出的分数,进行最后整合需要。及取前三,和总分。

  1. SELECT A.etor_id,fault_score_total,fault_code1,fault_score1,fault_des1,fault_code2,fault_score2,fault_des2,fault_code3,fault_score3,fault_des3 from
  2. (
  3. SELECT etor_id,[1] as fault_score1, [2] as fault_score2, [3] as fault_score3
  4. FROM
  5. (
  6. select a.etor_id,a.fault_score,a.fautl_score_range from (select t.*,row_number()over(partition by etor_id order by fault_score
  7. desc) as fautl_score_range from by_v_etor_fault_score_top3 t) a where fautl_score_range<=3
  8. )
  9. AS SourceTable
  10. PIVOT
  11. (
  12. MAX(fault_score) FOR fautl_score_range IN ([1], [2], [3])
  13. ) AS PivotTable
  14. )A
  15. LEFT JOIN
  16. (
  17. SELECT etor_id,[1] as fault_des1, [2] as fault_des2, [3] as fault_des3
  18. FROM
  19. (
  20. select a.etor_id,a.fault_desc,a.fautl_score_range from (select t.*,row_number()over(partition by etor_id order by fault_score
  21. desc) as fautl_score_range from by_v_etor_fault_score_top3 t) a where fautl_score_range<=3
  22. )
  23. AS SourceTable2
  24. PIVOT
  25. (
  26. MAX(fault_desc) FOR fautl_score_range IN ([1], [2], [3])
  27. ) AS PivotTable2
  28. )B on A.etor_id=B.etor_id
  29. LEFT JOIN
  30. (
  31. SELECT etor_id,[1] as fault_code1, [2] as fault_code2, [3] as fault_code3
  32. FROM
  33. (
  34. select a.etor_id,a.fault_code,a.fautl_score_range from (select t.*,row_number()over(partition by etor_id order by fault_score
  35. desc) as fautl_score_range from by_v_etor_fault_score_top3 t) a where fautl_score_range<=3
  36. )
  37. AS SourceTable2
  38. PIVOT
  39. (
  40. MAX(fault_code) FOR fautl_score_range IN ([1], [2], [3])
  41. ) AS PivotTable2
  42. )C on A.etor_id=C.etor_id
  43. LEFT JOIN
  44. (
  45. SELECT etor_id,sum(fault_score) as fault_score_total
  46. FROM
  47. by_v_etor_fault_score_top3
  48. GROUP BY etor_id
  49. )D on A.etor_id=D.etor_id

最终结果,这是便是我们要的结果



这只是我们用视图实现了我们要的结果,利用视图的直观性,中间有什么问题很方便调整,比如要添加设备的信息到最后表中应该也是很方便的。

后面我要把它设计成存储过程,因为其中还要涉及的故障发生的时间以便按月统计。




声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/953341
推荐阅读
相关标签
  

闽ICP备14008679号