所以我有一张桌子:
CREATE TABLE TABLE_NAME (
COLUMN_1 char(12) NOT NULL,
COLUMN_2 char(2) NOT NULL,
COLUMN_3 char(1) NOT NULL,
COLUMN_4 int NOT NULL,
COLUMN_5 char(2) NOT NULL,
COLUMN_6 money NOT NULL,
COLUMN_7 smallint NOT NULL,
COLUMN_8 varchar(10) NOT NULL,
COLUMN_9 smallint NOT NULL,
COLUMN_10 datetime NOT NULL
Primary Key (COLUMN_1, COLUMN_2, COLUMN_3)
)
SELECT COUNT(*)
返回的值不同于SELECT DISTINCT COUNT(*)
。怎么可能呢?
我也试过
SELECT COUNT(*) FROM (
SELECT
COLUMN_1,
COLUMN_2,
COLUMN_3,
COLUMN_4,
COLUMN_5,
COLUMN_6,
COLUMN_7,
COLUMN_8,
COLUMN_9,
COLUMN_10
FROM TABLE_NAME
) TMP
返回与不同查询相同的计数。
我有点累了,所以我希望我不会遗漏一些明显的东西,但是我看不到主键如何以及所有字段都是NOT NULL,总计数可能不同于独特的记录。
BTW,这是在Sybase ASE 15上。
差异是一百个左右的记录。我也在其他几个表中看到了这个问题,但只选择了一个例子。
编辑:
为了完整起见,我应该提一下,在编写一个简单的工作来将此表完全复制到远程数据库时,我发现了这个问题。我的应用程序记录了一定数量的读/写操作,但QA失败,因为源数据库中的记录数与目标数据库中的记录数不同。这两个值都是通过COUNT(*)获得的;从目标返回的计数(Oracle 10g)与我的应用程序记录的读/写操作数相同。由于源表上的所有字段都定义为NOT NULL并且定义了主键,因此我无法解释我的应用程序如何丢失少量记录。
这是我开始使用上面列出的备用查询时,这两个查询都同意我的应用程序读/写计数,以及从目标返回的COUNT()值。换句话说,唯一不匹配的值是源数据库上的COUNT()。
答案 0 :(得分:6)
在大多数支持它的数据库中,count(*)
实际上并不检索所有记录并对它们进行计数 - 而是取出一些元数据字段,它只跟踪当前存储的行数(或近似行数)桌子。另一方面,当你做一些需要处理实际数据的事情时,dbms仍然会获取行,并且它会按照你的预期计算它们。
当然,无论如何实现,count(*)
的结果与更复杂但等效的查询相同,都是合理的。那表明,(可能)你的表的元数据以某种方式被破坏了。 (我会说这个是一个不错的选择 - 我不熟悉sybase,但大多数dbms都有办法强制重建表指标......这可能值得一试)。
另一种可能的解释是,数据库的内部表行计数器实际上并未设计为100%准确。 (第二种可能性是纯粹受过教育的猜测......我实际上并不知道Sybase的行计数器是否属实,但可能值得进一步调查)。
祝你好运!答案 1 :(得分:1)
如果我没弄错的话,从这个判断:
你应该使用select count(distinct *)
。我希望select distinct count(*)
总是返回1,因为它说“给我不同的行,每个行都是count(*)
”,因此总会有一行,而{{1} }给出了不同行的计数。
FWIW,以上似乎是针对v12.5(虽然我没有看到任何差异),这里是15.0文档:
明确说明如下:
count(*)查找行数。 count(*)不带任何参数,不能与distinct 一起使用。无论是否存在空值,都会对所有行进行计数。
您可以使用select count(distinct *)
左右,但不能使用select count(distinct column_1)
。
答案 2 :(得分:1)