| | |
| | | from pat_med_inhosp |
| | | </sql> |
| | | |
| | | <sql id="selectPatMedInhospListFromWhere"> |
| | | pat_med_inhosp b |
| | | JOIN |
| | | pat_archive a ON a.id = b.patid |
| | | where 1=1 |
| | | <!-- |
| | | del_flag 必须用字符串常量比较:它取值是 '0'/'1'(char 列)。 |
| | | 写成 del_flag = 0 时 MySQL 会把【列】按 DOUBLE 隐式转换,该条件就只是过滤、 |
| | | 不能用来定位索引;而 b.del_flag 正是 idx_inhosp_optimize / idx_pmi_del_org_end |
| | | 的首列 —— 数字写法等于把索引首列白给。 |
| | | 同一结论见 sql/sltdMydTotalByDimension_index_20260924.sql 第 117-134 行。 |
| | | (列是 int 时写 '0' 也安全:转换发生在常量侧,索引照样可用。) |
| | | --> |
| | | AND a.del_flag = '0' |
| | | AND b.del_flag = '0' |
| | | AND a.idcardno IS NOT NULL |
| | | <if test="inhospid != null">and b.inhospid = #{inhospid}</if> |
| | | <if test="startOutHospTime != null ">and date_format(b.endtime,'%y%m%d') >= |
| | | date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null ">and date_format(b.endtime,'%y%m%d') <= |
| | | date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startInHospTime != null ">and date_format(b.starttime,'%y%m%d') >= |
| | | date_format(#{startInHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endInHospTime != null ">and date_format(b.starttime,'%y%m%d') <= |
| | | date_format(#{endInHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="hospitalname != null and hospitalname != ''">and hospitalname like concat('%', #{hospitalname}, |
| | | '%') |
| | | </if> |
| | | <if test="patname != null and patname != ''">and patname like concat('%', #{patname}, '%')</if> |
| | | <if test="hospitaldistrictname != null and hospitaldistrictname != ''">and hospitaldistrictname like |
| | | concat('%', #{hospitaldistrictname}, '%') |
| | | </if> |
| | | <if test="endtime != null ">and b.endtime = #{endtime}</if> |
| | | <if test="bedNo != null ">and b.bed_no = #{bedNo}</if> |
| | | <if test="inhospMydFlag != null ">and b.inhosp_myd_flag = #{inhospMydFlag}</if> |
| | | <if test="managementDoctor != null ">and b.management_doctor = #{managementDoctor}</if> |
| | | <if test="managementDoctorCode != null ">and b.management_doctor_code = #{managementDoctorCode}</if> |
| | | <if test="inhospno != null ">and b.inhospno = #{inhospno}</if> |
| | | <if test="fuflag != null ">and b.fuflag = #{fuflag}</if> |
| | | <if test="orgid != null ">and b.orgid = #{orgid}</if> |
| | | <if test="campusid != null ">and b.campusid = #{campusid}</if> |
| | | <if test="serialnum != null ">and b.serialnum = #{serialnum}</if> |
| | | <if test="endtime != null ">and b.endtime = #{endtime}</if> |
| | | <if test="patno != null ">and b.patno = #{patno}</if> |
| | | <if test="nurseId != null ">and b.nurse_id = #{nurseId}</if> |
| | | <if test="nurseName != null and nurseName != ''">and b.nurse_name = #{nurseName}</if> |
| | | <if test="deptcheckFlag != null ">and b.deptcheck_flag = #{deptcheckFlag}</if> |
| | | <if test="scheduleCheckFlag != null ">and b.schedulecheck_flag = #{scheduleCheckFlag}</if> |
| | | <if test="wardcheckFlag != null ">and b.wardcheck_flag = #{wardcheckFlag}</if> |
| | | <if test="inDeptcheckFlag != null ">and b.in_deptcheck_flag = #{inDeptcheckFlag}</if> |
| | | <if test="inWardcheckFlag != null ">and b.in_wardcheck_flag = #{inWardcheckFlag}</if> |
| | | <if test="diagcheckFlag != null ">and b.diagcheck_flag = #{diagcheckFlag}</if> |
| | | <if test="encounterSourceId != null ">and b.encounter_source_id = #{encounterSourceId}</if> |
| | | <if test="importanceFlagCode != null ">and b.importance_flag_code = #{importanceFlagCode}</if> |
| | | <if test="emergencyLevelCode != null ">and b.emergency_level_code = #{emergencyLevelCode}</if> |
| | | <!-- |
| | | 在院(cry=0):两个条件都要。 |
| | | ① b.endtime is null —— 原 XML 就有,保持不动; |
| | | ② b.inhospstate = '0' —— 迁出前由 PatMedInhospServiceImpl 补(cry=0 时 |
| | | setInhospstate("0")),迁到本模块后这条链直连 Mapper,这句就丢了。 |
| | | 为什么必须补回来(不只是"恢复原行为",也是性能问题): |
| | | · 索引 idx_inhosp_optimize / idx_pmi_del_org_state_end 的前三列是 |
| | | (del_flag, orgid, inhospstate),只有三个等值条件齐了才能精确定位"在院"那几千行; |
| | | 少了 inhospstate,就只能用到 (del_flag, orgid) 前缀 = 该机构【全部历史住院记录】, |
| | | 再加上后面的 ORDER BY/GROUP BY,实测就是 4~5 秒的来源。 |
| | | · cry=1/2/3 本来就是按 inhospstate 判的,只有 cry=0 用 endtime 判 —— 补齐后才对称。 |
| | | 为什么加 inhospstate == null 这个前提:调用方若已显式指定 inhospstate,就别和它打架 |
| | | (否则 cry=0 + inhospstate='2' 会变成"和自身矛盾"的空结果)。 |
| | | --> |
| | | <if test="cry != null and cry == 0 ">and b.endtime is null</if> |
| | | <if test="cry != null and cry == 0 and inhospstate == null ">and b.inhospstate = '0'</if> |
| | | <!-- 同 del_flag:inhospstate 是取值范围 '0'~'3' 的字符列,必须用字符串常量, |
| | | 否则索引上用不到这个等值条件(出院/转科/预入院 三个视图走的就是这三行) --> |
| | | <if test="cry != null and cry == 1 ">and b.inhospstate='1'</if> |
| | | <if test="cry != null and cry == 2 ">and b.inhospstate='2'</if> |
| | | <if test="cry != null and cry == 3 ">and b.inhospstate='3'</if> |
| | | <if test="inhospstate != null ">and b.inhospstate = #{inhospstate}</if> |
| | | <if test="schemestatus != null ">and b.schemestatus = #{schemestatus}</if> |
| | | <if test="outWayId != null ">and b.out_way_id = #{outWayId}</if> |
| | | <if test="outWayName != null ">and b.out_way_name = #{outWayName}</if> |
| | | <if test="leaveldeptcode != null ">and b.leaveldeptcode = #{leaveldeptcode}</if> |
| | | <if test="leavediagname != null and leavediagname != ''">and b.leavediagname like concat('%', |
| | | #{leavediagname}, '%') |
| | | </if> |
| | | <if test="drname != null and drname != ''">and b.drname like concat('%', #{drname}, '%')</if> |
| | | <if test="leaveldeptname != null and leaveldeptname != ''">and b.leaveldeptname like concat('%', |
| | | #{leaveldeptname}, '%') |
| | | </if> |
| | | <if test="deptname != null and deptname != ''">and b.deptname like concat('%', |
| | | #{deptname}, '%') |
| | | </if> |
| | | <if test="patid != null and patid != ''">and a.id =#{patid} |
| | | </if> |
| | | <if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and |
| | | b.leavehospitaldistrictname like concat('%', #{leavehospitaldistrictname}, '%') |
| | | </if> |
| | | |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0"> |
| | | AND b.leavehospitaldistrictcode IN |
| | | <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator="," |
| | | close=")"> |
| | | #{leavehospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | |
| | | <if test="hospitaldistrictcodeList != null and hospitaldistrictcodeList.size()>0"> |
| | | AND b.hospitaldistrictcode IN |
| | | <foreach collection="hospitaldistrictcodeList" item="hospitaldistrictcode" open="(" separator="," |
| | | close=")"> |
| | | #{hospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="leaveldeptcodes != null and leaveldeptcodes.size()>0"> |
| | | AND b.leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," |
| | | close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="deptcodeList != null and deptcodeList.size()>0"> |
| | | AND b.deptcode IN |
| | | <foreach collection="deptcodeList" item="deptcode" open="(" separator="," |
| | | close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="icd10codeList != null and icd10codeList.size()>0"> |
| | | AND b.leaveicd10code IN |
| | | <foreach collection="icd10codeList" item="icd10code" open="(" separator="," |
| | | close=")"> |
| | | #{icd10code} |
| | | </foreach> |
| | | </if> |
| | | <if test="medicalCode != null and medicalCode != ''">and b.medical_code = #{medicalCode}</if> |
| | | <if test="medicalName != null and medicalName != ''">and b.medical_name = #{medicalName}</if> |
| | | <if test="medicalCompany != null and medicalCompany != ''">and b.medical_company = #{medicalCompany}</if> |
| | | </sql> |
| | | |
| | | <select id="selectPatMedInhospList" parameterType="com.ruoyi.inhospvisit.domain.PatMedInhosp" resultMap="PatMedInhospResult"> |
| | | select a.age AS age, |
| | | a.telcode as telcode, |
| | |
| | | b.medical_company, |
| | | a.idcardno |
| | | FROM |
| | | pat_med_inhosp b |
| | | JOIN |
| | | pat_archive a ON a.id = b.patid |
| | | where 1=1 |
| | | AND a.del_flag = 0 |
| | | AND b.del_flag = 0 |
| | | AND a.idcardno IS NOT NULL |
| | | <if test="inhospid != null">and b.inhospid = #{inhospid}</if> |
| | | <if test="startOutHospTime != null ">and date_format(b.endtime,'%y%m%d') >= |
| | | date_format(#{startOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endOutHospTime != null ">and date_format(b.endtime,'%y%m%d') <= |
| | | date_format(#{endOutHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="startInHospTime != null ">and date_format(b.starttime,'%y%m%d') >= |
| | | date_format(#{startInHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="endInHospTime != null ">and date_format(b.starttime,'%y%m%d') <= |
| | | date_format(#{endInHospTime},'%y%m%d') |
| | | </if> |
| | | <if test="hospitalname != null and hospitalname != ''">and hospitalname like concat('%', #{hospitalname}, |
| | | '%') |
| | | </if> |
| | | <if test="patname != null and patname != ''">and patname like concat('%', #{patname}, '%')</if> |
| | | <if test="hospitaldistrictname != null and hospitaldistrictname != ''">and hospitaldistrictname like |
| | | concat('%', #{hospitaldistrictname}, '%') |
| | | </if> |
| | | <if test="endtime != null ">and b.endtime = #{endtime}</if> |
| | | <if test="bedNo != null ">and b.bed_no = #{bedNo}</if> |
| | | <if test="inhospMydFlag != null ">and b.inhosp_myd_flag = #{inhospMydFlag}</if> |
| | | <if test="managementDoctor != null ">and b.management_doctor = #{managementDoctor}</if> |
| | | <if test="managementDoctorCode != null ">and b.management_doctor_code = #{managementDoctorCode}</if> |
| | | <if test="inhospno != null ">and b.inhospno = #{inhospno}</if> |
| | | <if test="fuflag != null ">and b.fuflag = #{fuflag}</if> |
| | | <if test="orgid != null ">and b.orgid = #{orgid}</if> |
| | | <if test="campusid != null ">and b.campusid = #{campusid}</if> |
| | | <if test="serialnum != null ">and b.serialnum = #{serialnum}</if> |
| | | <if test="endtime != null ">and b.endtime = #{endtime}</if> |
| | | <if test="patno != null ">and b.patno = #{patno}</if> |
| | | <if test="nurseId != null ">and b.nurse_id = #{nurseId}</if> |
| | | <if test="nurseName != null and nurseName != ''">and b.nurse_name = #{nurseName}</if> |
| | | <if test="deptcheckFlag != null ">and b.deptcheck_flag = #{deptcheckFlag}</if> |
| | | <if test="scheduleCheckFlag != null ">and b.schedulecheck_flag = #{scheduleCheckFlag}</if> |
| | | <if test="wardcheckFlag != null ">and b.wardcheck_flag = #{wardcheckFlag}</if> |
| | | <if test="inDeptcheckFlag != null ">and b.in_deptcheck_flag = #{inDeptcheckFlag}</if> |
| | | <if test="inWardcheckFlag != null ">and b.in_wardcheck_flag = #{inWardcheckFlag}</if> |
| | | <if test="diagcheckFlag != null ">and b.diagcheck_flag = #{diagcheckFlag}</if> |
| | | <if test="encounterSourceId != null ">and b.encounter_source_id = #{encounterSourceId}</if> |
| | | <if test="importanceFlagCode != null ">and b.importance_flag_code = #{importanceFlagCode}</if> |
| | | <if test="emergencyLevelCode != null ">and b.emergency_level_code = #{emergencyLevelCode}</if> |
| | | <if test="cry != null and cry == 0 ">and b.endtime is null</if> |
| | | <if test="cry != null and cry == 1 ">and b.inhospstate=1</if> |
| | | <if test="cry != null and cry == 2 ">and b.inhospstate=2</if> |
| | | <if test="cry != null and cry == 3 ">and b.inhospstate=3</if> |
| | | <if test="inhospstate != null ">and b.inhospstate = #{inhospstate}</if> |
| | | <if test="schemestatus != null ">and b.schemestatus = #{schemestatus}</if> |
| | | <if test="outWayId != null ">and b.out_way_id = #{outWayId}</if> |
| | | <if test="outWayName != null ">and b.out_way_name = #{outWayName}</if> |
| | | <if test="leaveldeptcode != null ">and b.leaveldeptcode = #{leaveldeptcode}</if> |
| | | <if test="leavediagname != null and leavediagname != ''">and b.leavediagname like concat('%', |
| | | #{leavediagname}, '%') |
| | | </if> |
| | | <if test="drname != null and drname != ''">and b.drname like concat('%', #{drname}, '%')</if> |
| | | <if test="leaveldeptname != null and leaveldeptname != ''">and b.leaveldeptname like concat('%', |
| | | #{leaveldeptname}, '%') |
| | | </if> |
| | | <if test="deptname != null and deptname != ''">and b.deptname like concat('%', |
| | | #{deptname}, '%') |
| | | </if> |
| | | <if test="patid != null and patid != ''">and a.id =#{patid} |
| | | </if> |
| | | <if test="leavehospitaldistrictname != null and leavehospitaldistrictname != ''">and |
| | | b.leavehospitaldistrictname like concat('%', #{leavehospitaldistrictname}, '%') |
| | | </if> |
| | | |
| | | <if test="leavehospitaldistrictcodes != null and leavehospitaldistrictcodes.size()>0"> |
| | | AND b.leavehospitaldistrictcode IN |
| | | <foreach collection="leavehospitaldistrictcodes" item="leavehospitaldistrictcode" open="(" separator="," |
| | | close=")"> |
| | | #{leavehospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | |
| | | <if test="hospitaldistrictcodeList != null and hospitaldistrictcodeList.size()>0"> |
| | | AND b.hospitaldistrictcode IN |
| | | <foreach collection="hospitaldistrictcodeList" item="hospitaldistrictcode" open="(" separator="," |
| | | close=")"> |
| | | #{hospitaldistrictcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="leaveldeptcodes != null and leaveldeptcodes.size()>0"> |
| | | AND b.leaveldeptcode IN |
| | | <foreach collection="leaveldeptcodes" item="leaveldeptcode" open="(" separator="," |
| | | close=")"> |
| | | #{leaveldeptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="deptcodeList != null and deptcodeList.size()>0"> |
| | | AND b.deptcode IN |
| | | <foreach collection="deptcodeList" item="deptcode" open="(" separator="," |
| | | close=")"> |
| | | #{deptcode} |
| | | </foreach> |
| | | </if> |
| | | <if test="icd10codeList != null and icd10codeList.size()>0"> |
| | | AND b.leaveicd10code IN |
| | | <foreach collection="icd10codeList" item="icd10code" open="(" separator="," |
| | | close=")"> |
| | | #{icd10code} |
| | | </foreach> |
| | | </if> |
| | | <if test="medicalCode != null and medicalCode != ''">and b.medical_code = #{medicalCode}</if> |
| | | <if test="medicalName != null and medicalName != ''">and b.medical_name = #{medicalName}</if> |
| | | <if test="medicalCompany != null and medicalCompany != ''">and b.medical_company = #{medicalCompany}</if> |
| | | <include refid="selectPatMedInhospListFromWhere"/> |
| | | GROUP BY |
| | | b.inhospid, |
| | | a.age, |
| | |
| | | </otherwise> |
| | | </choose> |
| | | </if> |
| | | </select> |
| | | |
| | | <!-- |
| | | 分页总数(PageHelper 手写 count,id = 主查询 id + _COUNT 会被自动采用)。 |
| | | |
| | | 原状态:主查询带 GROUP BY,pagehelper 的 CountSqlParser#isSimpleCount 判定为 |
| | | "不能简化",于是总数变成 SELECT count(0) FROM ( 上面那条 60 列查询 ) tmp_count — |
| | | 等于每次翻页把整条查询再跑一遍。 |
| | | |
| | | 这里保持【完全相同的 FROM/WHERE/GROUP BY】(共用 selectPatMedInhospListFromWhere 片段, |
| | | 条件不会漂),但子查询只 select 1,不物化 60 列,也不带 order by。 |
| | | 因为分组键包含 a.id 而这个 join 是一对一,分组数 == join 结果行数,总数与原来一致。 |
| | | --> |
| | | <select id="selectPatMedInhospList_COUNT" parameterType="com.ruoyi.inhospvisit.domain.PatMedInhosp" |
| | | resultType="java.lang.Long"> |
| | | select count(1) |
| | | from ( |
| | | select 1 |
| | | FROM |
| | | <include refid="selectPatMedInhospListFromWhere"/> |
| | | group by b.inhospid, a.age, a.age_unit, a.telcode, a.id, a.sex |
| | | ) t |
| | | </select> |
| | | |
| | | <select id="selectPatMedInhospListBySerialnum" parameterType="com.ruoyi.inhospvisit.domain.PatMedInhosp" |
| | |
| | | order by b.inhospid desc |
| | | </select> |
| | | |
| | | <!-- |
| | | 在院信息刷新的取数:只查 pat_med_inhosp 自身、只取刷新要用的列。 |
| | | 刻意不复用 selectPatMedInhospList —— 那个查询 join 了 pat_archive 且要求 |
| | | a.idcardno IS NOT NULL,会让"证件号还没补上的新入院患者"静默漏刷新。 |
| | | WHERE (del_flag, orgid, inhospstate) 命中 idx_inhosp_optimize 的前缀。 |
| | | --> |
| | | <select id="selectInhospRefreshCandidates" resultMap="PatMedInhospResult"> |
| | | select inhospid, |
| | | serialnum, |
| | | patname, |
| | | orgid, |
| | | campusid, |
| | | deptcode, |
| | | deptname, |
| | | hospitaldistrictcode, |
| | | hospitaldistrictname, |
| | | hospitaldistrictid, |
| | | bed_no |
| | | from pat_med_inhosp |
| | | where inhospstate = '0' |
| | | and del_flag = '0' |
| | | and orgid = #{orgid} |
| | | order by inhospid asc |
| | | </select> |
| | | |
| | | <select id="selectPatMedInhospListByCondition" parameterType="com.ruoyi.inhospvisit.domain.PatMedInhospVO" |
| | | resultMap="PatMedInhospResult"> |
| | | select CONCAT( a.age, a.age_unit ) AS age, |