所以,这很奇怪,这是我以前从未见过的。我希望有人有一个神奇的答案可以解释这个问题......
SELECT * FROM TABLE -- returns rows... a lot of rows
然而,
SELECT COUNT(1) FROM TABLE -- returns zero (0), as in the number zero (0) as the result
这是表结构:
CREATE TABLE TRACKING (
A_ID NUMBER,
D_CODE NUMBER,
HOD NUMBER,
ADR_CNT NUMBER,
TTL_CNT NUMBER,
CREATED DATE,
MODIFIED DATE
);
CREATE INDEX HOD_D_CODE_IDX ON TRACKING (HOD, D_CODE);
CREATE UNIQUE INDEX TRACKING_PK ON TRACKING (A_ID, D_CODE, HOD);
CREATE INDEX MOD_DATE_IDX ON TRACKING (MODIFIED);
ALTER TABLE TRACKING ADD CONSTRAINT TRACKING_PK PRIMARY KEY (A_ID, D_CODE, HOD);
Oracle表如何有行但count(1)返回零?我在网上做了一些搜索,但一无所获。我发现的唯一其他帖子与MS SQL Server有关。这种情况发生在Oracle。
有什么想法吗?任何人吗?
提前感谢您提供的任何帮助。
我可能会添加另一件事,希望它能帮助回答这个难题,这个表被Oracle Job用来聚合和填充另一个表。但是,现在已经完成了几天。另一个表已完全填充并显示预期记录计数。我检查了Oracle作业日志,它显示了所有成功,而不是一个错误。
答案 0 :(得分:1)
错误的结果可能是由于静默更改SQL语句的损坏,错误和功能造成的。
为了排除#3,下面的代码向您展示了执行此操作的邪恶方法之一,以及如何检测它。首先,创建架构和一些数据:
CREATE TABLE TRACKING (
A_ID NUMBER,
D_CODE NUMBER,
HOD NUMBER,
ADR_CNT NUMBER,
TTL_CNT NUMBER,
CREATED DATE,
MODIFIED DATE
);
CREATE INDEX HOD_D_CODE_IDX ON TRACKING (HOD, D_CODE);
CREATE UNIQUE INDEX TRACKING_PK ON TRACKING (A_ID, D_CODE, HOD);
CREATE INDEX MOD_DATE_IDX ON TRACKING (MODIFIED);
ALTER TABLE TRACKING ADD CONSTRAINT TRACKING_PK PRIMARY KEY (A_ID, D_CODE, HOD);
insert into tracking values (1,2,3,4,5,sysdate,sysdate);
commit;
首先,一切都按预期工作:
SQL> SELECT * FROM TRACKING;
A_ID D_CODE HOD ADR_CNT TTL_CNT CREATED MODIFIED
---------- ---------- ---------- ---------- ---------- --------- ---------
1 2 3 4 5 17-JUN-16 17-JUN-16
SQL> SELECT COUNT(1) FROM TRACKING;
COUNT(1)
----------
1
然后有人这样做:
begin
sys.dbms_advanced_rewrite.declare_rewrite_equivalence(
'april_fools',
'SELECT COUNT(1) FROM TRACKING',
'SELECT 0 FROM TRACKING WHERE ROWNUM = 1',
false);
end;
/
现在结果是"错误":
SQL> ALTER SESSION SET query_rewrite_integrity = trusted;
Session altered.
SQL> SELECT COUNT(1) FROM TRACKING;
COUNT(1)
----------
0
这可以通过查看解释计划来检测。在下面的示例中,谓词2 - filter(ROWNUM=1)
是一个错误的线索,因为该谓词不在原始查询中。有时"注意"解释计划的一部分将告诉你为什么它被转换,但有时它只提供线索。
SQL> explain plan for SELECT COUNT(1) FROM TRACKING;
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------
Plan hash value: 1761840423
------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 2 | 1 (0)| 00:00:01 |
| 1 | VIEW | | 1 | 2 | 1 (0)| 00:00:01 |
|* 2 | COUNT STOPKEY | | | | | |
| 3 | INDEX FULL SCAN| HOD_D_CODE_IDX | 1 | | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - filter(ROWNUM=1)
15 rows selected.
(在不相关的注释上 - 始终使用COUNT(*)
代替COUNT(1)
。COUNT(1)
是一个古老的神话,看起来像货物崇拜节目。)
答案 1 :(得分:-1)
COUNT(SomeColumn)将仅返回包含SomeColumn的非空值的行数。 COUNT(*)和COUNT(' Foo')将返回表格中的总行数。
您的列1是否可能对所有寄存器都为NULL?如果它根本没有NULL,它应该作为Count(*)返回该表中的所有行,如果是这种情况,我们需要更多信息来帮助你。