Oracle客户站点查询问题:仅需当日修改的站点记录
优化后的SQL解决方案
原查询的核心问题在于:Trunc(hop.LAST_UPDATE_DATE) = Trunc(SYSDATE)是客户(party)级别的条件,只要该客户的组织信息被修改,所有关联站点都会被返回;而Trunc(HP.CREATION_DATE) = Trunc(SYSDATE)会返回当日创建的客户的所有站点,这两者都不符合“仅返回修改的单个站点”的需求。
根据你描述的“修改仅发生在hz_organization_profiles和hz_locations”,以及示例场景,以下是两种针对性的优化方案:
方案1:仅返回位置信息(hzl)当日修改的站点
这是最贴合你示例的方案,仅当站点对应的位置记录被修改时才返回该站点:
SELECT -- hz_parties 字段 hp.party_id, hp.party_name, hp.jgzz_fiscal_code, TO_CHAR(hp.creation_date, 'DD/MM/YYYY') AS creation_date, -- hz_party_sites 字段 hps.party_site_id, hps.party_site_number, -- hz_organization_profiles 字段 hop.attribute2, hop.attribute1, hop.attribute3, -- hz_locations 字段 hzl.attribute6, hzl.postal_code, hzl.address1, hzl.addr_element_attribute3, hzl.state, hzl.addr_element_attribute2, hzl.city, hzl.attribute1, CASE WHEN hzl.attribute7 IS NULL THEN NULL ELSE ( SELECT vst1.description FROM fnd_vs_values_b vsv1 JOIN fnd_vs_values_tl vst1 ON vsv1.value_id = vst1.value_id AND vsv1.enterprise_id = vst1.enterprise_id AND vsv1.sandbox_id = vst1.sandbox_id WHERE vsv1.value = hzl.attribute7 AND vsv1.attribute_category = 'Periodo de facturación' AND vst1.language = 'E' ) END AS "PeriodoFacturacionId", hzl.attribute4 AS "LimiteCredito", hzl.attribute3 AS "ClienteId", -- Vendedor 子查询 ( SELECT vst1.description FROM fnd_vs_values_b vsv1 JOIN fnd_vs_values_tl vst1 ON vsv1.value_id = vst1.value_id AND vsv1.enterprise_id = vst1.enterprise_id AND vsv1.sandbox_id = vst1.sandbox_id WHERE vsv1.value = hzl.attribute2 AND vsv1.attribute_category = 'Vendedor' AND vst1.language = 'E' ) AS "Vendedor" FROM hz_parties hp JOIN hz_party_sites hps ON hp.party_id = hps.party_id AND hp.party_type = 'ORGANIZATION' JOIN hz_organization_profiles hop ON hp.party_id = hop.party_id JOIN hz_locations hzl ON hps.location_id = hzl.location_id WHERE TRUNC(hzl.last_update_date) = TRUNC(SYSDATE);
方案2:返回位置修改的站点 + 客户组织信息修改的所有站点
如果需要同时包含“客户组织信息当日修改”的所有站点(比如客户的统一信息更新),可以保留hop的条件,但移除客户创建日期的条件:
SELECT -- 字段同方案1,省略重复部分 hp.party_id, hp.party_name, hp.jgzz_fiscal_code, TO_CHAR(hp.creation_date, 'DD/MM/YYYY') AS creation_date, hps.party_site_id, hps.party_site_number, hop.attribute2, hop.attribute1, hop.attribute3, hzl.attribute6, hzl.postal_code, hzl.address1, hzl.addr_element_attribute3, hzl.state, hzl.addr_element_attribute2, hzl.city, hzl.attribute1, CASE WHEN hzl.attribute7 IS NULL THEN NULL ELSE ( SELECT vst1.description FROM fnd_vs_values_b vsv1 JOIN fnd_vs_values_tl vst1 ON vsv1.value_id = vst1.value_id AND vsv1.enterprise_id = vst1.enterprise_id AND vsv1.sandbox_id = vst1.sandbox_id WHERE vsv1.value = hzl.attribute7 AND vsv1.attribute_category = 'Periodo de facturación' AND vst1.language = 'E' ) END AS "PeriodoFacturacionId", hzl.attribute4 AS "LimiteCredito", hzl.attribute3 AS "ClienteId", ( SELECT vst1.description FROM fnd_vs_values_b vsv1 JOIN fnd_vs_values_tl vst1 ON vsv1.value_id = vst1.value_id AND vsv1.enterprise_id = vst1.enterprise_id AND vsv1.sandbox_id = vst1.sandbox_id WHERE vsv1.value = hzl.attribute2 AND vsv1.attribute_category = 'Vendedor' AND vst1.language = 'E' ) AS "Vendedor" FROM hz_parties hp JOIN hz_party_sites hps ON hp.party_id = hps.party_id AND hp.party_type = 'ORGANIZATION' JOIN hz_organization_profiles hop ON hp.party_id = hop.party_id JOIN hz_locations hzl ON hps.location_id = hzl.location_id WHERE TRUNC(hzl.last_update_date) = TRUNC(SYSDATE) OR TRUNC(hop.last_update_date) = TRUNC(SYSDATE);
关键修改说明
- 改用ANSI JOIN语法:替代旧的逗号分隔连接,逻辑更清晰,避免隐式连接导致的意外结果。
- 移除客户创建日期条件:
Trunc(HP.CREATION_DATE) = Trunc(SYSDATE)会返回当日创建的客户的所有站点,不符合“修改的站点”需求,若确需保留可自行加回。 - 精准筛选站点级修改:方案1仅保留
hzl的更新日期条件,确保只有单个修改的站点被返回,完全匹配你的示例场景。 - 优化子查询连接方式:子查询改用JOIN替代逗号连接,提升可读性和执行效率。
内容的提问来源于stack exchange,提问作者Cesar Tepetla
相关产品推荐
相关产品推荐

