sql - Oracle SQL 按带计数的列分组,但仅当该列为空或 0 时

标签 sql oracle plsql group-by

简而言之,我试图按列分组,但前提是该列不是 null0,在这种情况下我仍然想获取这些行,但只是没有分组。我有这张表some_table:

+--------+----------+---------------------+-------+
| id     | other_id | date_value          | value |
+--------+----------+---------------------+-------+
| 1      | abc      | 2011-04-20 21:03:05 | 104   |
| 2      | abc      | 2011-04-20 21:03:04 | 229   |
| 3      | xyz      | 2011-04-20 21:03:03 | 130   |
| 4      | abc      | 2011-04-20 21:02:09 | 97    |
| 5      | 0        | 2011-04-20 21:02:08 | 65    |
| 6      | xyz      | 2011-04-20 21:02:07 | 101   |
| 7      |          | 2011-04-20 21:02:07 | 200   |
| 8      | 0        | 2011-04-20 21:02:07 | 201   |
| 9      |          | 2011-04-20 21:02:07 | 202   |
+--------+----------+---------------------+-------+

我想按 other_id 选择行和分组,还包括分组行的计数。此查询有效:

select id, other_id, date_value, value, cnt from
 (
   SELECT id, other_id, date_value, value, 
   ROW_NUMBER() OVER (partition by other_id order BY Date_Value desc) r,
   count(*) OVER (partition by other_id) cnt
   FROM some_table 
 )
where r = 1

结果是:

+--------+----------+---------------------+-------+-------+
| id     | other_id | date_value          | value | count |
+--------+----------+---------------------+-------+-------+
| 1      | abc      | 2011-04-20 21:03:05 | 104   | 3     |
| 3      | xyz      | 2011-04-20 21:03:03 | 130   | 2     |
| 5      | 0        | 2011-04-20 21:02:08 | 65    | 2     |
| 7      |          | 2011-04-20 21:02:07 | 200   | 2     |
+--------+----------+---------------------+-------+-------+

问题是,我不想对 other_idnull0 的行进行分组。所以想要的结果是这样的:

+--------+----------+---------------------+-------+-------+
| id     | other_id | date_value          | value | count |
+--------+----------+---------------------+-------+-------+
| 1      | abc      | 2011-04-20 21:03:05 | 104   | 3     |
| 3      | xyz      | 2011-04-20 21:03:03 | 130   | 2     |
| 5      | 0        | 2011-04-20 21:02:08 | 65    | 1     |
| 7      |          | 2011-04-20 21:02:07 | 200   | 1     |
| 8      | 0        | 2011-04-20 21:02:07 | 201   | 1     |
| 9      |          | 2011-04-20 21:02:07 | 202   | 1     |
+--------+----------+---------------------+-------+-------+

如您所见,所有内容都已分组,除非 other_idnull0,在这种情况下它们仍处于选中状态,但未分组.我还尝试按 date_value 订购。

我尝试在 OVER 子句中添加一个 WHERE 子句:

OVER (partition by other_id WHERE other_id IS NOT NULL AND other_id IS NOT '0' order BY Date_Value desc)
-- this produces an error: ORA-00907: missing right parenthesis

我考虑过执行第二个 select 查询并尝试将第一个结果堆叠在第二个结果之上,但我认为这不会起作用,因为顺序。

有什么方法可以根据条件进行这样的分组吗?

最佳答案

这样做就可以了:

SQL> select id, other_id, date_value, value, cnt from
  2   (
  3     SELECT id, other_id, date_value, value,
  4     case
  5       when other_id is null or other_id = '0' then 1
  6       else ROW_NUMBER() OVER (partition by other_id order BY Date_Value desc)
  7     end r,
  8     case
  9       when other_id is null or other_id = '0' then 1
 10       else count(*) OVER (partition by other_id)
 11     end cnt
 12     FROM some_table
 13   )
 14  where r = 1
 15  order by id;

        ID OTH DATE_VALUE               VALUE        CNT
---------- --- ------------------- ---------- ----------
         1 abc 2011-04-20 21:03:05        104          3
         3 xyz 2011-04-20 21:03:03        130          2
         5 0   2011-04-20 21:02:08         65          1
         7     2011-04-20 21:02:07        200          1
         8 0   2011-04-20 21:02:07        201          1
         9     2011-04-20 21:02:07        202          1

6 rows selected.

SQL>

关于sql - Oracle SQL 按带计数的列分组,但仅当该列为空或 0 时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14400235/

相关文章:

sql - 验证 sql/oracle 中的电子邮件/邮政编码字段

INET6_ATON 和 NTOA 函数的 Oracle PL/SQL 版本?

database - Linux 中的 TNS 条目

java - 从 Oracle 中返回表的函数中选择的其他方法

oracle - ORACLE PL/SQL 中有计算多边形面积的函数吗?

没有 LIMIT 的 MySQL SELECT 查询

asp.net - 是否有与 Oracle 等效的 Microsoft SQL Profiler

mysql - SQL 使用行作为列

java - 在 PreparedStatement 中使用 setDate

sql - 只要我们选择正确的连接类型,连接表的顺序就无关紧要吗?