Oracle Group by NULL 中的 SQL 返回多行

Posted

技术标签:

【中文标题】Oracle Group by NULL 中的 SQL 返回多行【英文标题】:SQL in Oracle Group by NULL returns multiple rows 【发布时间】:2014-09-06 03:43:36 【问题描述】:

我有一个 sql 语句,它试图检索所有相似行的计数大于 1 的行。在所有这些行中,一个字段似乎包含空值。

案例一:

假设表名是 ABC


BUSINESS_UNIT、发票、旗帜

A 1(空)

A 1(空)


SQL 语句:SELECT BUSINESS_UNIT, INVOICE, FLAG from TABLE ABC group by BUSINESS_UNIT, INVOICE, FLAG COUNT(*) > 1

我希望它不会返回任何行,因为这两个标志基本上都是空白的。但它返回


BUSINESS_UNIT、发票、旗帜

A 1(空)


案例 2:

表 ABC


BUSINESS_UNIT、发票、旗帜

A 1(空)

A 1(空)

B 1 1

B 1(空)


SQL 语句:SELECT BUSINESS_UNIT, INVOICE, FLAG from TABLE ABC group by BUSINESS_UNIT, INVOICE, FLAG COUNT(*) >1

我期待结果是


BUSINESS_UNIT、发票、旗帜

B 1 1


这是针对 Oracle 11g 的。有人可以帮忙,让我知道我们是否可以使用 Oracle 中提供的任何功能吗?


编辑原始sql语句后。

我实际上应该从 Group by 中删除标志并选择并添加到计数中,以便识别相似行的多个标志。


谢谢!

【问题讨论】:

【参考方案1】:

嗯,null 也是一个值,所以如果您按可空字段分组,则 null 值将不同于非 null 值。

如果你不想空值,只需添加一个 where 子句

SELECT INVOICE 
from TABLE ABC 
where flag is not null
group by BUSINESS_UNIT, INVOICE, FLAG 
having COUNT(*) >1

【讨论】:

感谢 Raphael 的回答,过滤器将在案例 1 中工作,但对于案例 2,它不会按预期工作。 @startedFromTheBottom 没有什么可以使您的第二个查询工作...1 <> NULL @startedFromTheBottom 除非 flag 只能为 1 或 null。是这样,还是不是? Raphaël : Flag 只能是 1、2 或 null。现在我在想我不应该将标志放在组中,并以某种方式计算我拥有的不同标志的数量,并在计算标志时使用(NVL 将 null 作为一些随机数)。你有什么建议? @startedFromTheBottom 嗯,我被困在这里:如果你有B, 1, 1B, 1, nullB, 1, 2,你想检索什么?【参考方案2】:

这是您的第一个查询:

SELECT BUSINESS_UNIT, INVOICE, FLAG
from TABLE ABC
group by BUSINESS_UNIT, INVOICE, FLAG
having COUNT(*) > 1;

count(*) 正在返回每个组中的行数。其中一个组是flagNULL 值全部组合在一起。如果你想统计flag的非NULL值,那么你可以使用:

SELECT BUSINESS_UNIT, INVOICE, FLAG
from TABLE ABC
group by BUSINESS_UNIT, INVOICE, FLAG
having COUNT(flag) > 1;

或者按照 Raphaël Althaus 的建议进行过滤。

您的第二个查询是:

SELECT INVOICE
from TABLE ABC
group by BUSINESS_UNIT, INVOICE, FLAG
having COUNT(*) > 1;

select 中只有一列时,您似乎神奇地想要输出中的三列。是的,如果你真的想要的话,group by 中的列可以比select 中的列更多。

你的最后一个问题是:

有人可以帮忙吗,如果我们可以使用任何一个,请告诉我 Oracle 中提供的函数?

当然可以。 Oracle 有一套非常强大的功能。它们中的大多数都与 ANSI 标准一致,并且在 Oracle 和其他数据库上的行为方式相同。您只需要学习如何正确使用它们。

【讨论】:

@RaphaëlAlthaus 。 . .我的键盘没有那些有趣的字符 ;) 幸运的是,剪切和粘贴有效。干杯。 哦,我不是要 ë,只是 ph ;) 无论如何,开个玩笑! 感谢 Gordon 的回复,我正在尝试确定按相同字段(业务单位和发票)分组但在这些行上有不同标志且标志为空的行数。我已经更新了案例2的sql语句中的字段数。我想我在group by中添加标志是错误的。【参考方案3】:

除了按照 Raphaël Althaus 的建议添加 WHERE 子句之外,您还可以将 count(*) 更改为 count(flag):

SELECT INVOICE 
from TABLE ABC 
group by BUSINESS_UNIT, INVOICE, FLAG 
having COUNT(flag) >1

【讨论】:

您好,dnoeth,感谢您的回复,我认为我不应该在组中添加 FLAG。我们可以从组中删除 FLAG 并使用 COUNT(flag) > 1。同样,如果相似行有两个 null,它将检索我不期望的行。【参考方案4】:

我想我已经找到了我想要寻找的东西。

选择 BUSINESS_UNIT,发票 从表 ABC 按 BUSINESS_UNIT、INVOICE 分组 具有 COUNT(DISTINCT 标志) >1

案例 1:它不返回任何行

案例2:返回1行


BUSINESS_UNIT,发票

B 1


感谢 Raphael、Dnoeth 和 Gordon 在这方面的帮助!

【讨论】:

以上是关于Oracle Group by NULL 中的 SQL 返回多行的主要内容,如果未能解决你的问题,请参考以下文章

oracle中的group by和union

oracle group by 性能优化

[Database] Oracle 中的where 可以后接group by

oracle语句中的聚合函数以及分组group by的使用实例

如何在不使用 GROUP BY 或 PARTITION BY 的情况下对 Oracle SQL 中的数据进行分组

oracle sql中的group by表达式的内部连接[重复]