SQL - 计算分区

Posted

技术标签:

【中文标题】SQL - 计算分区【英文标题】:SQL - count over partition 【发布时间】: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 参数来管理隐式转换。特别是如果这种情况发生了变化,您的代码很可能会失败。 按您未显示的列进行分区也有点奇怪。您确定要分析计数,而不是汇总吗?您能否编辑问题以包含表结构、一些示例数据和您要查找的结果? 【参考方案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';

【讨论】:

以上是关于SQL - 计算分区的主要内容,如果未能解决你的问题,请参考以下文章

sql server 分区

SQL:如何使用多列分区计算百分比增加

按国家和条件索引计算 SQL 分区中的市场总和 [关闭]

Oracle sql计算分区上的不同值?

从 SQL 窗口函数中排除分区?

BigQuery:计算每日分区表中的平均值