【问题标题】:SQL - count over partitionSQL - 计算分区
【发布时间】:2016-11-16 15:11:41
【问题描述】:

请告诉我这有什么问题:

 select 
 p.date,
 (SELECT COUNT (*) OVER (PARTITION BY p.ID_code)
 FROM POOL_AREA.F_volume_GCOA p
 WHERE p.end_volume_KN <> 0
 AND p.date                = '31-OCT-16'
 AND (p.local_grade_MB IS NULL OR p.local_grade_MB ='0' OR          p.local_grade_MB ='N')) AS ERROR_CNT
 FROM POOL_AREA.F_volume_GCOA p
 where p.date                = '31-OCT-16';

过度分区部分是问题,没有它,它可以工作。

错误详情:
ORA-01427: 单行子查询返回多于一行
01427. 00000 - “单行子查询返回多行”
*原因:
*行动:

【问题讨论】:

  • 首先,您有一个Oracle 错误消息,但您将问题标记为MySQLSQL Server
  • 通过分区你会得到不止一个结果。在您的选择中,它可能只有一个值。您可以加入子查询而不是将其添加到您的 SELECT
  • 为什么这里有一个子查询? date 也是保留字,不是有效的列名; '31-OCT-16' 是字符串而不是日期。如果您使用正确的数据类型,生活会更轻松。有一列存储“N”和“0”看起来也很奇怪。
  • @Ema 顺便说一句,p.date 是什么数据类型?如果是 DATE,那么您不应该将日期与字符串进行比较。 IE。将p.date = '31-OCT-16' 更改为p.date = to_date('31/10/2016', 'dd/mm/yyyy')。这样,您就不会依赖 nls_date_format 参数来管理隐式转换。特别是如果这种情况发生了变化,您的代码很可能会失败。
  • 按您未显示的列进行分区也有点奇怪。您确定要分析计数,而不是汇总吗?您能否编辑问题以包含表结构、一些示例数据和您要查找的结果?

标签: sql oracle window-functions


【解决方案1】:

我认为你真正追求的是条件计数 - 类似于:

select   p.dt,
         count(case when p.end_volume_kn != 0
                         and (p.local_grade_mb is null
                              or p.local_grade_mb in ('0', 'N'))
                         then 1
               end) error_cnt
FROM     POOL_AREA.F_volume_GCOA p
where    p.dt = to_date('31/10/2016', 'dd/mm/yyyy')
group by p.dt;

【讨论】:

    【解决方案2】:

    如 cmets 中所述,类似这样的内容(未测试):

    select 
     p.date,
     t.val AS ERROR_CNT    
    
     FROM POOL_AREA.F_volume_GCOA p
     JOIN (SELECT p.ID_code, COUNT (*) as val  OVER (PARTITION BY p2.ID_code)
     FROM POOL_AREA.F_volume_GCOA p2
     WHERE p2.end_volume_KN <> 0
     AND p2.date                = '31-OCT-16'
     AND (p2.local_grade_MB IS NULL OR p2.local_grade_MB ='0' 
         OR  p.local_grade_MB ='N')) as t ON t.ID_Code = p.ID_code
     where p.date                = '31-OCT-16';
    

    【讨论】:

      【解决方案3】:

      这行得通!

       select 
       p.date,
       (SELECT COUNT (*) FROM
      (SELECT DISTINCT p.id_code
       FROM POOL_AREA.F_volume_GCOA p
       WHERE p.end_volume_KN <> 0
      AND p.date                = '31-OCT-16'
      AND (p.local_grade_MB IS NULL OR p.local_grade_MB ='0' OR              p.local_grade_MB ='N'))) AS ERROR_CNT
      FROM POOL_AREA.F_volume_GCOA p
       where p.date                = '31-OCT-16';
      

      【讨论】:

        猜你喜欢
        • 2011-01-03
        • 2021-03-22
        • 2021-10-18
        • 1970-01-01
        • 2021-09-22
        • 2012-06-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多