diagnose_quota_display_issue_final.sql 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. -- ===================================================================
  2. -- 奖学金名额显示问题诊断脚本 (最终修正版)
  3. -- 创建时间: 2025-01-27
  4. -- 目的: 检查班级名额分配和奖学金类型的数据完整性
  5. -- 表名修正: xg_class_msg, jcbt_scholarship_class_quota
  6. -- ===================================================================
  7. -- 1. 检查当前班主任和班级信息
  8. SELECT
  9. '=== 1. 班主任和班级信息检查 ===' as info;
  10. SELECT
  11. u.user_id,
  12. u.user_name,
  13. u.nick_name,
  14. c.id as class_id,
  15. c.class_name,
  16. c.grade,
  17. c.college_id,
  18. c.major_id
  19. FROM sys_user u
  20. LEFT JOIN xg_class_msg c ON u.user_id = c.class_teacher_id
  21. WHERE u.user_type = '03' -- 班主任
  22. AND c.id IS NOT NULL
  23. ORDER BY c.id;
  24. -- 2. 检查奖学金批次信息
  25. SELECT
  26. '=== 2. 奖学金批次信息检查 ===' as info;
  27. SELECT
  28. id as batch_id,
  29. batch_name,
  30. status as batch_status,
  31. start_time,
  32. end_time,
  33. create_time
  34. FROM jcbt_scholarship_batch
  35. WHERE status = 'ACTIVE' -- 启用状态
  36. ORDER BY create_time DESC;
  37. -- 3. 检查奖学金类型信息
  38. SELECT
  39. '=== 3. 奖学金类型信息检查 ===' as info;
  40. SELECT
  41. st.id as type_id,
  42. st.type_name,
  43. st.level_type,
  44. st.status as type_status,
  45. bt.batch_id,
  46. b.batch_name
  47. FROM jcbt_scholarship_type st
  48. LEFT JOIN jcbt_scholarship_batch_type bt ON st.id = bt.scholarship_type_id
  49. LEFT JOIN jcbt_scholarship_batch b ON bt.batch_id = b.id
  50. WHERE st.status = 1 -- 启用状态
  51. ORDER BY st.level_type, st.type_name;
  52. -- 4. 检查班级名额分配情况
  53. SELECT
  54. '=== 4. 班级名额分配情况检查 ===' as info;
  55. SELECT
  56. cq.id as quota_id,
  57. cq.batch_id,
  58. b.batch_name,
  59. cq.scholarship_type_id,
  60. st.type_name,
  61. cq.class_id,
  62. c.class_name,
  63. cq.total_quota,
  64. cq.used_quota,
  65. cq.available_quota,
  66. cq.allocation_method,
  67. cq.status,
  68. cq.create_time
  69. FROM jcbt_scholarship_class_quota cq
  70. LEFT JOIN jcbt_scholarship_batch b ON cq.batch_id = b.id
  71. LEFT JOIN jcbt_scholarship_type st ON cq.scholarship_type_id = st.id
  72. LEFT JOIN xg_class_msg c ON cq.class_id = c.id
  73. ORDER BY cq.batch_id, cq.class_id, cq.scholarship_type_id;
  74. -- 5. 检查已使用名额情况
  75. SELECT
  76. '=== 5. 已使用名额情况检查 ===' as info;
  77. SELECT
  78. sa.batch_id,
  79. b.batch_name,
  80. sa.scholarship_type_id,
  81. st.type_name,
  82. sa.applicant_class_id,
  83. c.class_name,
  84. COUNT(*) as actual_used_quota,
  85. GROUP_CONCAT(sa.application_status) as status_list
  86. FROM jcbt_scholarship_application sa
  87. LEFT JOIN jcbt_scholarship_batch b ON sa.batch_id = b.batch_id
  88. LEFT JOIN jcbt_scholarship_type st ON sa.scholarship_type_id = st.type_id
  89. LEFT JOIN xg_class_msg c ON sa.applicant_class_id = c.id
  90. WHERE sa.application_status IN ('submitted', 'approved') -- 有效申请
  91. GROUP BY sa.batch_id, sa.scholarship_type_id, sa.applicant_class_id
  92. ORDER BY sa.batch_id, sa.applicant_class_id, sa.scholarship_type_id;
  93. -- 6. 检查名额使用情况汇总与一致性
  94. SELECT
  95. '=== 6. 名额使用情况汇总与一致性检查 ===' as info;
  96. SELECT
  97. cq.batch_id,
  98. b.batch_name,
  99. cq.class_id,
  100. c.class_name,
  101. cq.scholarship_type_id,
  102. st.type_name,
  103. cq.total_quota,
  104. cq.used_quota as recorded_used_quota,
  105. COALESCE(actual_used.used_count, 0) as actual_used_quota,
  106. cq.available_quota as recorded_available_quota,
  107. (cq.total_quota - COALESCE(actual_used.used_count, 0)) as calculated_available_quota,
  108. CASE
  109. WHEN cq.used_quota != COALESCE(actual_used.used_count, 0) THEN 'INCONSISTENT'
  110. WHEN cq.available_quota != (cq.total_quota - COALESCE(actual_used.used_count, 0)) THEN 'INCONSISTENT'
  111. ELSE 'CONSISTENT'
  112. END as consistency_status,
  113. CASE
  114. WHEN cq.total_quota = 0 THEN 'unlimited'
  115. WHEN (cq.total_quota - COALESCE(actual_used.used_count, 0)) > 0 THEN 'available'
  116. ELSE 'full'
  117. END as quota_status
  118. FROM jcbt_scholarship_class_quota cq
  119. LEFT JOIN jcbt_scholarship_batch b ON cq.batch_id = b.batch_id
  120. LEFT JOIN jcbt_scholarship_type st ON cq.scholarship_type_id = st.type_id
  121. LEFT JOIN xg_class_msg c ON cq.class_id = c.id
  122. LEFT JOIN (
  123. SELECT
  124. batch_id,
  125. scholarship_type_id,
  126. applicant_class_id,
  127. COUNT(*) as used_count
  128. FROM jcbt_scholarship_application
  129. WHERE application_status IN ('submitted', 'approved')
  130. GROUP BY batch_id, scholarship_type_id, applicant_class_id
  131. ) actual_used ON cq.batch_id = actual_used.batch_id
  132. AND cq.scholarship_type_id = actual_used.scholarship_type_id
  133. AND cq.class_id = actual_used.applicant_class_id
  134. ORDER BY cq.batch_id, cq.class_id, cq.scholarship_type_id;
  135. -- 7. 检查特定班级的详细情况(以班级ID=1为例)
  136. SELECT
  137. '=== 7. 特定班级详细情况检查 (class_id=1) ===' as info;
  138. SELECT
  139. '班级基本信息:' as section,
  140. c.id as class_id,
  141. c.class_name,
  142. c.grade,
  143. c.class_teacher_id,
  144. u.user_name as class_teacher_name,
  145. u.nick_name as class_teacher_nick
  146. FROM xg_class_msg c
  147. LEFT JOIN sys_user u ON c.class_teacher_id = u.user_id
  148. WHERE c.id = 1;
  149. SELECT
  150. '该班级的名额分配:' as section,
  151. cq.scholarship_type_id,
  152. st.type_name,
  153. cq.total_quota,
  154. cq.used_quota,
  155. cq.available_quota,
  156. cq.allocation_method,
  157. cq.status
  158. FROM jcbt_scholarship_class_quota cq
  159. LEFT JOIN jcbt_scholarship_type st ON cq.scholarship_type_id = st.type_id
  160. WHERE cq.class_id = 1
  161. ORDER BY cq.scholarship_type_id;
  162. -- 8. 检查数据完整性问题
  163. SELECT
  164. '=== 8. 数据完整性问题检查 ===' as info;
  165. -- 检查缺少名额分配的奖学金类型
  166. SELECT
  167. '缺少名额分配的奖学金类型:' as issue_type,
  168. st.type_id,
  169. st.type_name,
  170. bt.batch_id,
  171. b.batch_name,
  172. COUNT(DISTINCT c.id) as total_classes_without_quota
  173. FROM jcbt_scholarship_type st
  174. INNER JOIN jcbt_scholarship_batch_type bt ON st.type_id = bt.type_id
  175. INNER JOIN jcbt_scholarship_batch b ON bt.batch_id = b.batch_id
  176. CROSS JOIN xg_class_msg c
  177. LEFT JOIN jcbt_scholarship_class_quota cq ON st.type_id = cq.scholarship_type_id
  178. AND bt.batch_id = cq.batch_id
  179. AND c.id = cq.class_id
  180. WHERE st.type_status = '1'
  181. AND b.batch_status = '1'
  182. AND c.class_status = '1'
  183. AND cq.id IS NULL
  184. GROUP BY st.type_id, st.type_name, bt.batch_id, b.batch_name;
  185. -- 检查有名额分配但奖学金类型不存在的情况
  186. SELECT
  187. '名额分配指向不存在的奖学金类型:' as issue_type,
  188. cq.id as quota_id,
  189. cq.scholarship_type_id,
  190. cq.batch_id,
  191. cq.class_id
  192. FROM jcbt_scholarship_class_quota cq
  193. LEFT JOIN jcbt_scholarship_type st ON cq.scholarship_type_id = st.type_id
  194. WHERE st.type_id IS NULL;
  195. -- 检查名额分配指向不存在的班级
  196. SELECT
  197. '名额分配指向不存在的班级:' as issue_type,
  198. cq.id as quota_id,
  199. cq.class_id,
  200. cq.class_name as recorded_class_name
  201. FROM jcbt_scholarship_class_quota cq
  202. LEFT JOIN xg_class_msg c ON cq.class_id = c.id
  203. WHERE c.id IS NULL;
  204. -- 9. 模拟API查询结果
  205. SELECT
  206. '=== 9. 模拟API查询结果 (batch_id=1, class_id=1) ===' as info;
  207. SELECT
  208. st.type_id,
  209. st.type_name,
  210. st.type_level,
  211. st.type_description,
  212. CASE
  213. WHEN cq.total_quota IS NULL THEN 0
  214. ELSE cq.total_quota
  215. END as total_quota,
  216. CASE
  217. WHEN cq.used_quota IS NULL THEN 0
  218. ELSE cq.used_quota
  219. END as used_quota,
  220. CASE
  221. WHEN cq.available_quota IS NULL THEN 0
  222. WHEN cq.total_quota = 0 THEN 999999
  223. ELSE cq.available_quota
  224. END as available_quota,
  225. CASE
  226. WHEN cq.total_quota IS NULL THEN FALSE
  227. WHEN cq.total_quota = 0 THEN FALSE
  228. ELSE TRUE
  229. END as has_quota,
  230. CASE
  231. WHEN cq.total_quota IS NULL THEN 'no_allocation'
  232. WHEN cq.total_quota = 0 THEN 'unlimited'
  233. WHEN cq.available_quota > 0 THEN 'available'
  234. ELSE 'full'
  235. END as quota_status,
  236. cq.allocation_method,
  237. cq.status as allocation_status
  238. FROM jcbt_scholarship_type st
  239. INNER JOIN jcbt_scholarship_batch_type bt ON st.type_id = bt.type_id
  240. LEFT JOIN jcbt_scholarship_class_quota cq ON st.type_id = cq.scholarship_type_id
  241. AND bt.batch_id = cq.batch_id
  242. AND cq.class_id = 1
  243. WHERE bt.batch_id = 1
  244. AND st.type_status = '1'
  245. ORDER BY
  246. CASE quota_status
  247. WHEN 'available' THEN 1
  248. WHEN 'unlimited' THEN 2
  249. WHEN 'full' THEN 3
  250. WHEN 'no_allocation' THEN 4
  251. END,
  252. st.type_level,
  253. st.type_name;
  254. -- 10. 额外检查:验证数据同步问题
  255. SELECT
  256. '=== 10. 数据同步问题检查 ===' as info;
  257. -- 检查used_quota和available_quota字段是否需要更新
  258. SELECT
  259. 'need_quota_update' as check_type,
  260. cq.id,
  261. cq.batch_id,
  262. cq.class_id,
  263. cq.scholarship_type_id,
  264. cq.total_quota,
  265. cq.used_quota as recorded_used,
  266. COALESCE(actual.actual_used, 0) as actual_used,
  267. cq.available_quota as recorded_available,
  268. (cq.total_quota - COALESCE(actual.actual_used, 0)) as calculated_available
  269. FROM jcbt_scholarship_class_quota cq
  270. LEFT JOIN (
  271. SELECT
  272. batch_id,
  273. scholarship_type_id,
  274. applicant_class_id,
  275. COUNT(*) as actual_used
  276. FROM jcbt_scholarship_application
  277. WHERE application_status IN ('submitted', 'approved')
  278. GROUP BY batch_id, scholarship_type_id, applicant_class_id
  279. ) actual ON cq.batch_id = actual.batch_id
  280. AND cq.scholarship_type_id = actual.scholarship_type_id
  281. AND cq.class_id = actual.applicant_class_id
  282. WHERE cq.used_quota != COALESCE(actual.actual_used, 0)
  283. OR cq.available_quota != (cq.total_quota - COALESCE(actual.actual_used, 0));