refactor(doctorstation): 优化医生站医嘱查询SQL逻辑

- 将原有的条件判断逻辑重构为更清晰的choose/when/otherwise结构
- 修复了adviceTypes参数为空或未指定时的SQL执行问题
- 通过trim标签处理UNION ALL连接避免多余关键字
- 添加otherwise分支确保无adviceTypes时返回正确空结果集
- 保持了原有的所有功能逻辑和数据映射关系不变
- 提高了SQL查询的可读性和维护性
This commit is contained in:
2026-01-15 13:42:36 +08:00
parent d8080fa22d
commit 8f1ad3307c

View File

@@ -43,208 +43,249 @@
abi.restricted_scope, abi.restricted_scope,
abi.dosage_instruction, abi.dosage_instruction,
abi.chrgitm_lv abi.chrgitm_lv
from ( FROM (
<if test="adviceTypes == null or adviceTypes.contains(1)"> <choose>
(SELECT <when test="adviceTypes != null and !adviceTypes.isEmpty()">
DISTINCT ON (T1.ID) <trim prefixOverrides="UNION ALL">
T1.tenant_id, <if test="adviceTypes.contains(1)">
1 AS advice_type, (SELECT
T1.bus_no AS bus_no, DISTINCT ON (T1.ID)
T1.category_code AS category_code, T1.tenant_id,
T1.pharmacology_category_code AS pharmacology_category_code, 1 AS advice_type,
T1.part_percent AS part_percent, T1.bus_no AS bus_no,
T1.unit_conversion_ratio AS unit_conversion_ratio, T1.category_code AS category_code,
T1.part_attribute_enum AS part_attribute_enum, T1.pharmacology_category_code AS pharmacology_category_code,
T1.tho_part_attribute_enum AS tho_part_attribute_enum, T1.part_percent AS part_percent,
T1.skin_test_flag AS skin_test_flag, T1.unit_conversion_ratio AS unit_conversion_ratio,
T1.inject_flag AS inject_flag, T1.part_attribute_enum AS part_attribute_enum,
T1.ID AS advice_definition_id, T1.tho_part_attribute_enum AS tho_part_attribute_enum,
T1.NAME AS advice_name, T1.skin_test_flag AS skin_test_flag,
T1.bus_no AS advice_bus_no, T1.inject_flag AS inject_flag,
T1.py_str AS py_str, T1.ID AS advice_definition_id,
T1.wb_str AS wb_str, T1.NAME AS advice_name,
T1.yb_no AS yb_no, T1.bus_no AS advice_bus_no,
T1.merchandise_name AS product_name, T1.py_str AS py_str,
0 AS activity_type, T1.wb_str AS wb_str,
T1.unit_code AS unit_code, T1.yb_no AS yb_no,
T1.min_unit_code AS min_unit_code, T1.merchandise_name AS product_name,
T2.total_volume AS volume, 0 AS activity_type,
T2.method_code AS method_code, T1.unit_code AS unit_code,
T2.rate_code AS rate_code, T1.min_unit_code AS min_unit_code,
T2.org_id AS org_id, T2.total_volume AS volume,
T2.location_id AS location_id, T2.method_code AS method_code,
CAST(T2.dose AS TEXT) AS dose, T2.rate_code AS rate_code,
T2.dose_unit_code AS dose_unit_code, T2.org_id AS org_id,
T3.NAME AS supplier, T2.location_id AS location_id,
T3.id AS supplier_id, CAST(T2.dose AS TEXT) AS dose,
T1.manufacturer_text AS manufacturer, T2.dose_unit_code AS dose_unit_code,
T5.id AS charge_item_definition_id, T3.NAME AS supplier,
T5.instance_table AS advice_table_name, T3.id AS supplier_id,
T6.def_location_id AS position_id, T1.manufacturer_text AS manufacturer,
t1.restricted_flag AS restricted_flag, T5.id AS charge_item_definition_id,
t1.restricted_scope AS restricted_scope, T5.instance_table AS advice_table_name,
T1.dosage_instruction AS dosage_instruction, T6.def_location_id AS position_id,
T1.chrgitm_lv as chrgitm_lv t1.restricted_flag AS restricted_flag,
FROM med_medication_definition AS t1 t1.restricted_scope AS restricted_scope,
INNER JOIN med_medication AS T2 ON T2.medication_def_id = T1.ID T1.dosage_instruction AS dosage_instruction,
AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum} T1.chrgitm_lv as chrgitm_lv
LEFT JOIN adm_supplier AS T3 FROM med_medication_definition AS t1
ON T3.ID = T1.supply_id INNER JOIN med_medication AS T2 ON T2.medication_def_id = T1.ID
AND T3.delete_flag = '0' AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
LEFT JOIN adm_charge_item_definition AS T5 ON T5.instance_id = T1.ID LEFT JOIN adm_supplier AS T3
AND T5.delete_flag = '0' AND T5.status_enum = #{statusEnum} ON T3.ID = T1.supply_id
LEFT JOIN adm_organization_location AS T6 AND T3.delete_flag = '0'
ON T6.distribution_category_code = T1.category_code LEFT JOIN adm_charge_item_definition AS T5 ON T5.instance_id = T1.ID
AND T6.delete_flag = '0' AND T6.item_code = '1' AND T6.organization_id = #{organizationId} AND AND T5.delete_flag = '0' AND T5.status_enum = #{statusEnum}
(CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time) LEFT JOIN adm_organization_location AS T6
WHERE T1.delete_flag = '0' ON T6.distribution_category_code = T1.category_code
AND T2.status_enum = #{statusEnum} AND T6.delete_flag = '0' AND T6.item_code = '1' AND T6.organization_id = #{organizationId} AND
<if test="pricingFlag ==1"> (CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
AND 1 = 2 WHERE T1.delete_flag = '0'
</if> AND T2.status_enum = #{statusEnum}
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()"> <if test="pricingFlag ==1">
AND T1.id IN AND 1 = 2
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")"> </if>
#{itemId} <if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
</foreach> AND T1.id IN
</if> <foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
AND T5.instance_table = #{medicationTableName} #{itemId}
) </foreach>
</if> </if>
AND T5.instance_table = #{medicationTableName}
)
</if>
<if test="adviceTypes.contains(2)">
UNION ALL
(SELECT
DISTINCT ON (T1.ID)
T1.tenant_id,
2 AS advice_type,
T1.bus_no AS bus_no,
T1.category_code AS category_code,
'' AS pharmacology_category_code,
T1.part_percent AS part_percent,
0 AS unit_conversion_ratio,
null AS part_attribute_enum,
null AS tho_part_attribute_enum,
null AS skin_test_flag,
null AS inject_flag,
T1.ID AS advice_definition_id,
T1.NAME AS advice_name,
T1.bus_no AS advice_bus_no,
T1.py_str AS py_str,
T1.wb_str AS wb_str,
T1.yb_no AS yb_no,
'' AS product_name,
0 AS activity_type,
T1.unit_code AS unit_code,
T1.min_unit_code AS min_unit_code,
T1.SIZE AS volume,
'' AS method_code,
'' AS rate_code,
T1.org_id AS org_id,
T1.location_id AS location_id,
'' AS dose,
'' AS dose_unit_code,
T2.NAME AS supplier,
T2.id AS supplier_id,
T1.manufacturer_text AS manufacturer,
T4.id AS charge_item_definition_id,
T4.instance_table AS advice_table_name,
T5.def_location_id AS position_id,
0 AS restricted_flag,
'' AS restricted_scope,
'' AS dosage_instruction,
T1.chrgitm_lv as chrgitm_lv
FROM adm_device_definition AS T1
LEFT JOIN adm_supplier AS T2
ON T2.ID = T1.supply_id
AND T2.delete_flag = '0'
LEFT JOIN adm_charge_item_definition AS T4 ON T4.instance_id = T1.ID
AND T4.delete_flag = '0' AND T4.status_enum = #{statusEnum}
LEFT JOIN adm_organization_location AS T5 ON T5.distribution_category_code = T1.category_code
AND T5.delete_flag = '0' AND T5.item_code = '2' AND T5.organization_id = #{organizationId} AND
(CURRENT_TIME :: time (6) BETWEEN T5.start_time AND T5.end_time)
WHERE T1.delete_flag = '0'
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
AND T1.id IN
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
#{itemId}
</foreach>
</if>
AND T4.instance_table = #{deviceTableName}
AND T1.status_enum = #{statusEnum}
)
</if>
<if test="adviceTypes == null or adviceTypes.contains(1)"> <if test="adviceTypes.contains(3)">
<if test="adviceTypes == null or adviceTypes.contains(2) or adviceTypes.contains(3)">UNION ALL</if> UNION ALL
</if> (SELECT
DISTINCT ON (T1.ID)
<if test="adviceTypes == null or adviceTypes.contains(2)"> T1.tenant_id,
(SELECT 3 AS advice_type,
DISTINCT ON (T1.ID) T1.bus_no AS bus_no,
T1.tenant_id, T1.category_code AS category_code,
2 AS advice_type, '' AS pharmacology_category_code,
T1.bus_no AS bus_no, 1 AS part_percent,
T1.category_code AS category_code, 0 AS unit_conversion_ratio,
'' AS pharmacology_category_code, null AS part_attribute_enum,
T1.part_percent AS part_percent, null AS tho_part_attribute_enum,
0 AS unit_conversion_ratio, null AS skin_test_flag,
null AS part_attribute_enum, null AS inject_flag,
null AS tho_part_attribute_enum, T1.ID AS advice_definition_id,
null AS skin_test_flag, T1.NAME AS advice_name,
null AS inject_flag, T1.bus_no AS advice_bus_no,
T1.ID AS advice_definition_id, T1.py_str AS py_str,
T1.NAME AS advice_name, T1.wb_str AS wb_str,
T1.bus_no AS advice_bus_no, T1.yb_no AS yb_no,
T1.py_str AS py_str, '' AS product_name,
T1.wb_str AS wb_str, T1.type_enum AS activity_type,
T1.yb_no AS yb_no, '' AS unit_code,
'' AS product_name, '' AS min_unit_code,
0 AS activity_type, '' AS volume,
T1.unit_code AS unit_code, '' AS method_code,
T1.min_unit_code AS min_unit_code, '' AS rate_code,
T1.SIZE AS volume, T1.org_id AS org_id,
'' AS method_code, T1.location_id AS location_id,
'' AS rate_code, '' AS dose,
T1.org_id AS org_id, '' AS dose_unit_code,
T1.location_id AS location_id, '' AS supplier,
'' AS dose, null AS supplier_id,
'' AS dose_unit_code, '' AS manufacturer,
T2.NAME AS supplier, T2.ID AS charge_item_definition_id,
T2.id AS supplier_id, T2.instance_table AS advice_table_name,
T1.manufacturer_text AS manufacturer, T3.organization_id AS position_id,
T4.id AS charge_item_definition_id, 0 AS restricted_flag,
T4.instance_table AS advice_table_name, '' AS restricted_scope,
T5.def_location_id AS position_id, '' AS dosage_instruction,
0 AS restricted_flag, T1.chrgitm_lv as chrgitm_lv
'' AS restricted_scope, FROM wor_activity_definition AS T1
'' AS dosage_instruction, LEFT JOIN adm_charge_item_definition AS T2
T1.chrgitm_lv as chrgitm_lv ON T2.instance_id = T1.ID
FROM adm_device_definition AS T1 AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
LEFT JOIN adm_supplier AS T2 AND T2.instance_table = #{activityTableName}
ON T2.ID = T1.supply_id LEFT JOIN adm_organization_location AS T3 ON T3.activity_definition_id = T1.ID
AND T2.delete_flag = '0' AND T3.delete_flag = '0' AND (CURRENT_TIME :: time (6) BETWEEN T3.start_time AND T3.end_time)
LEFT JOIN adm_charge_item_definition AS T4 ON T4.instance_id = T1.ID WHERE T1.delete_flag = '0'
AND T4.delete_flag = '0' AND T4.status_enum = #{statusEnum} <if test="pricingFlag ==1">
LEFT JOIN adm_organization_location AS T5 ON T5.distribution_category_code = T1.category_code AND (T1.pricing_flag = #{pricingFlag} OR T1.pricing_flag IS NULL)
AND T5.delete_flag = '0' AND T5.item_code = '2' AND T5.organization_id = #{organizationId} AND </if>
(CURRENT_TIME :: time (6) BETWEEN T5.start_time AND T5.end_time) <if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
WHERE T1.delete_flag = '0' AND T1.id IN
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()"> <foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
AND T1.id IN #{itemId}
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")"> </foreach>
#{itemId} </if>
</foreach> AND T1.status_enum = #{statusEnum}
</if> )
AND T4.instance_table = #{deviceTableName} </if>
AND T1.status_enum = #{statusEnum} </trim>
) </when>
</if> <otherwise>
-- 当没有指定adviceTypes或adviceTypes为空时返回空结果集但保持正确的SQL语法
SELECT
<if test="adviceTypes == null or adviceTypes.contains(2)"> NULL::varchar AS tenant_id,
<if test="adviceTypes == null or adviceTypes.contains(3)">UNION ALL</if> NULL::integer AS advice_type,
</if> NULL::varchar AS bus_no,
NULL::varchar AS category_code,
<if test="adviceTypes == null or adviceTypes.contains(3)"> NULL::varchar AS pharmacology_category_code,
(SELECT NULL::numeric AS part_percent,
DISTINCT ON (T1.ID) NULL::numeric AS unit_conversion_ratio,
T1.tenant_id, NULL::integer AS part_attribute_enum,
3 AS advice_type, NULL::integer AS tho_part_attribute_enum,
T1.bus_no AS bus_no, NULL::integer AS skin_test_flag,
T1.category_code AS category_code, NULL::integer AS inject_flag,
'' AS pharmacology_category_code, NULL::bigint AS advice_definition_id,
1 AS part_percent, NULL::varchar AS advice_name,
0 AS unit_conversion_ratio, NULL::varchar AS advice_bus_no,
null AS part_attribute_enum, NULL::varchar AS py_str,
null AS tho_part_attribute_enum, NULL::varchar AS wb_str,
null AS skin_test_flag, NULL::varchar AS yb_no,
null AS inject_flag, NULL::varchar AS product_name,
T1.ID AS advice_definition_id, NULL::integer AS activity_type,
T1.NAME AS advice_name, NULL::varchar AS unit_code,
T1.bus_no AS advice_bus_no, NULL::varchar AS min_unit_code,
T1.py_str AS py_str, NULL::numeric AS volume,
T1.wb_str AS wb_str, NULL::varchar AS method_code,
T1.yb_no AS yb_no, NULL::varchar AS rate_code,
'' AS product_name, NULL::bigint AS org_id,
T1.type_enum AS activity_type, NULL::bigint AS location_id,
'' AS unit_code, NULL::varchar AS dose,
'' AS min_unit_code, NULL::varchar AS dose_unit_code,
'' AS volume, NULL::varchar AS supplier,
'' AS method_code, NULL::bigint AS supplier_id,
'' AS rate_code, NULL::varchar AS manufacturer,
T1.org_id AS org_id, NULL::bigint AS charge_item_definition_id,
T1.location_id AS location_id, NULL::varchar AS advice_table_name,
'' AS dose, NULL::bigint AS position_id,
'' AS dose_unit_code, NULL::integer AS restricted_flag,
'' AS supplier, NULL::varchar AS restricted_scope,
null AS supplier_id, NULL::varchar AS dosage_instruction,
'' AS manufacturer, NULL::integer AS chrgitm_lv
T2.ID AS charge_item_definition_id, WHERE 1 = 0 -- 确保不返回任何行
T2.instance_table AS advice_table_name, </otherwise>
T3.organization_id AS position_id, </choose>
0 AS restricted_flag,
'' AS restricted_scope,
'' AS dosage_instruction,
T1.chrgitm_lv as chrgitm_lv
FROM wor_activity_definition AS T1
LEFT JOIN adm_charge_item_definition AS T2
ON T2.instance_id = T1.ID
AND T2.delete_flag = '0' AND T2.status_enum = #{statusEnum}
AND T2.instance_table = #{activityTableName}
LEFT JOIN adm_organization_location AS T3 ON T3.activity_definition_id = T1.ID
AND T3.delete_flag = '0' AND (CURRENT_TIME :: time (6) BETWEEN T3.start_time AND T3.end_time)
WHERE T1.delete_flag = '0'
<if test="pricingFlag ==1">
AND (T1.pricing_flag = #{pricingFlag} OR T1.pricing_flag IS NULL)
</if>
<if test="adviceDefinitionIdParamList != null and !adviceDefinitionIdParamList.isEmpty()">
AND T1.id IN
<foreach collection="adviceDefinitionIdParamList" item="itemId" open="(" separator="," close=")">
#{itemId}
</foreach>
</if>
AND T1.status_enum = #{statusEnum}
)
</if>
) AS abi ) AS abi
${ew.customSqlSegment} ${ew.customSqlSegment}
</select> </select>