Sql 开发更好的代码

Sql 开发更好的代码,sql,oracle,oraclereports,Sql,Oracle,Oraclereports,分歧 select CE1.CLASS_ID, CE1.LOCATION_ID, count(case CE1.FORMAT_ID when 5 then 1 end) as LIVE, count(case CE1.FORMAT_ID when 14 then 1 end) as LB, count(case CE1.FORMAT_ID when 15 then 1 end) as WEB,

分歧

  select CE1.CLASS_ID, 
         CE1.LOCATION_ID,
         count(case CE1.FORMAT_ID  when 5 then 1 end) as LIVE,
         count(case CE1.FORMAT_ID  when 14 then 1 end) as LB,
         count(case CE1.FORMAT_ID  when 15 then 1 end) as WEB,
         SUM(DECODE (CE1.ROLE_ID,5,1,0)) FACULTY,
         SUM(DECODE  (CE1.ROLE_ID ,2,1,0)) MODERATOR,
         SUM(DECODE  (CE1.ROLE_ID ,3,1,0)) PANELIST,  
         SUM(DECODE  (CE1.ROLE_ID,4,1,0)) PRESENTER,
         COUNT(CE1.USER_ID) TOT 
    from C_EDUCATION1 CE1 
GROUP BY CE1.LOCATION_ID, CE1.CLASS_ID
我们正在开发现有的系统,我们发现混合使用计数和解码。 如果我们理解正确,我们可以转换为以下代码

  select CE1.CLASS_ID,  
         CE1.LOCATION_ID, 
         SUM(DECODE (CE1.FORMAT_ID ,5,1,0)) LIVE,
         SUM(DECODE  (CE1.FORMAT_ID ,14,1,0)) LB, 
         SUM(DECODE  (CE1.FORMAT_ID,15,1,0)) WEB,
         SUM(DECODE (CE1.ROLE_ID,5,1,0)) FACULTY,
         SUM(DECODE  (CE1.ROLE_ID ,2,1,0)) MODERATOR,
         SUM(DECODE  (CE1.ROLE_ID ,3,1,0)) PANELIST,  
         SUM(DECODE  (CE1.ROLE_ID,4,1,0)) PRESENTER,
         COUNT(CE1.USER_ID) TOT 
    from C_EDUCATION1 CE1 
GROUP BY CE1.LOCATION_ID, CE1.CLASS_ID
或 都算

我们想知道性能上的差异或其他问题。
它是一种更好的存在方式吗?

两者之间不会有性能差异

就个人而言,我倾向于选择基于案例的解决方案。CASE是ANSI标准,而不是Oracle特定的函数。来自其他数据库平台的开发人员可能必须查找DECODE语句的语义。对于开发人员来说,无论他们熟悉哪种语言,这种情况也相对明显。实际上,每种语言都有一个CASE语句,因此任何开发人员都应该能够快速看到您正在做什么

话虽如此,我倾向于提倡

SELECT ce1.class_id,
       ce1.location_id,
       SUM( CASE WHEN format_pkg.is_live( format_id ) = 'Y' THEN 1 ELSE 0 END ) live,
       SUM( CASE WHEN format_pkg.is_lb(   format_id ) = 'Y' THEN 1 ELSE 0 END ) lb,
       ...

这将使用第一个查询的大小写和第二个查询的总和,并添加一些函数调用以确定正在讨论的格式/角色类型。这就避免了您必须到处硬编码格式\u ID/角色\u ID值。使用SUM而不是COUNT更清楚一些,因为COUNT排除空值对开发人员来说可能不是很明显。

两者之间没有性能差异

就个人而言,我倾向于选择基于案例的解决方案。CASE是ANSI标准,而不是Oracle特定的函数。来自其他数据库平台的开发人员可能必须查找DECODE语句的语义。对于开发人员来说,无论他们熟悉哪种语言,这种情况也相对明显。实际上,每种语言都有一个CASE语句,因此任何开发人员都应该能够快速看到您正在做什么

话虽如此,我倾向于提倡

SELECT ce1.class_id,
       ce1.location_id,
       SUM( CASE WHEN format_pkg.is_live( format_id ) = 'Y' THEN 1 ELSE 0 END ) live,
       SUM( CASE WHEN format_pkg.is_lb(   format_id ) = 'Y' THEN 1 ELSE 0 END ) lb,
       ...

这将使用第一个查询的大小写和第二个查询的总和,并添加一些函数调用以确定正在讨论的格式/角色类型。这就避免了您必须到处硬编码格式\u ID/角色\u ID值。使用SUM而不是COUNT更清楚一些,因为对于开发人员来说,COUNT排除空值可能不是很明显。

我不知道使用CASE和DECODE之间的性能差异,但是CASE是ANSI的,因此如果用DECODE替换CASE,查询将更具可移植性。我认为解码是被贬低的,但它不会因为向后兼容性而消失。为了清楚起见,您的案例变体应该包含一个EXT子句。我假设默认值为NULL,这不计算在内,但是对于系统的、一致的编码,在所有版本中都使用SUM-然后您肯定需要一个ELSE子句。我不知道使用CASE和DECODE之间的性能差异,但是CASE是ANSI,因此如果将DECODE替换为CASE,查询将更便于移植。我认为解码是被贬低的,但它不会因为向后兼容性而消失。为了清楚起见,您的案例变体应该包含一个EXT子句。我假设默认值为NULL,这将不被计算在内,但是对于系统的、一致的编码,在所有版本中使用SUM-然后您肯定需要一个ELSE子句。