2

无论函数 COUNT() 括号内的参数是什么,以下三个代码片段的结果都是一样的,为什么?

SELECT Category.Category, Category.CategoryID, COUNT(Category) AS Popularity
FROM FavCategory INNER JOIN Category
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
HAVING COUNT(FavCategory.MemberID)>=2;

SELECT Category.Category, Category.CategoryID, COUNT(FavCategory.CategoryID) AS Popularity
FROM FavCategory INNER JOIN Category
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
HAVING COUNT(FavCategory.CategoryID)>=4;

SELECT Category.Category, Category.CategoryID, COUNT(FavCategory.MemberID) AS Popularity
FROM FavCategory INNER JOIN Category
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
HAVING COUNT(FavCategory.MemberID)>=2;

SELECT Category.Category, Category.CategoryID, COUNT(FavCategory.MemberID+Category.CategoryID) AS Popularity
FROM FavCategory INNER JOIN Category
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
HAVING COUNT(FavCategory.MemberID)>=2;

这是 Category 和 FavCategory 表上的记录 在此处输入图像描述

4

4 回答 4

2

你在问为什么。它们都是相同的,COUNT取决于字段/表达式是否为 null 或 null。如果该值不为空,COUNT则计算它;如果为空,则忽略它

您的表上没有任何空值,因此所有三个查询都报告相同的值。尝试COUNT('DRACULA'), COUNT(42),COUNT(0)甚至,对于 CategoryID 3 和 2 对于 CategoryID 1COUNT(-1) ,它们将计为 3 ,它们的工作方式与您的三个查询相同。

当然,COUNT(*)如果你正在使用,你也可以使用INNER JOIN,并且它是可取的。如果你正在使用LEFT JOIN,使用不正确COUNT(*),你必须这样做:COUNT(secondTable.foreignKeyColumnHere); 或者如果 Access 支持基于基数的计数(如在 Postgresql 中),只需执行以下操作:COUNT(secondTable.*)

有关计数和正确使用启蒙的入门知识(插头警报),请阅读我在http://www.ienablemuch.com/2010/04/debunking-myth-that-c​​ountdracula -is.html 上关于计数的帖子


@JDein

鉴于此数据:

create table Person
(
  PersonId int not null primary key, 
  Name varchar(100) not null, 
  Middlename varchar(100) null
);

insert into Person(PersonId,Name,MiddleName) values
(1,'John','Winston'),
(2,'Paul','James'),
(3,'George',NULL),
(4,'Ringo','Parkin');

所有这些都将返回 4:

select count(PersonID) from Person;

select count(Name) from Person;

select count(*) from Person;

select count(1) from Person;

select count(0) from Person;

select count(2) from Person;

select count(-1) from Person;

select count(42) from Person;

select count('Dracula') from Person;

除以下内容外,这将返回 3:

select count(MiddleName) from Person;

现场测试:http ://www.sqlfiddle.com/#!3/c1b1e/8

于 2012-05-23T06:30:55.587 回答
1

如果您希望在结果中更容易看到受欢迎程度,您可能应该添加一个ORDER BY子句来按 COUNT 列对结果进行排序:

SELECT
  Category.Category,
  Category.CategoryID,
  COUNT(FavCategory.MemberID) AS Popularity
FROM FavCategory INNER JOIN Category
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
HAVING COUNT(FavCategory.MemberID)>=2
ORDER BY Popularity DESC;

也许您还想包括不在最喜欢的类别中的类别。在这种情况下,您需要替换INNER JOINLEFT JOIN交换连接的两侧:

SELECT
  Category.Category,
  Category.CategoryID,
  COUNT(FavCategory.MemberID) AS Popularity
FROM Category LEFT JOIN FavCategory
ON FavCategory.CategoryID= Category.CategoryID
GROUP BY Category, Category.CategoryID
ORDER BY Popularity DESC;

另请注意,在这种情况下,计算连接表 ( FavCategory) 列之一的值(MemberID在上面的示例中)是至关重要的。如果某些类别在 中没有匹配项FavCategoriesMemberID则为 NULL,因此不计入 COUNT。

于 2012-05-23T06:52:55.303 回答
1

我的猜测是,您实际上是在为该列寻找不同的值,在这种情况下使用:

COUNT(DISTINCT (FavCategory.CategoryID))

(ETC)。

来自COUNT 的 SQL Server 文档(您尚未指定要使用的数据库):

COUNT(ALL expression) 计算组中每一行的表达式并返回非空值的数量。

(我相信 ALL 是默认值,而不是 DISTINCT。)

鉴于您的表中没有任何值是空值,因此仅使用表达式就相当于COUNT(*)- 即它将返回组的行数。这就是为什么每个表达式都给出相同的结果。

如果您不追求明显的结果,请说明您想要达到的目标,我们或许可以提出替代方案。(好吧,其他人也许可以——我怀疑我不会,作为一个 SQL 初学者。)

于 2012-05-23T05:55:18.743 回答
0

您正在尝试获取 Category、Category.CategoryID 组合的行数。这意味着 DB 将创建这 2 个列的所有 unq 组合,然后打印每个 unq 组合的行数。如果您在 group 子句和 where 子句中具有相同的 cols,那么您的行数将不会改变。可以影响行数但没有数据可以查看它很难判断它是否有任何影响

于 2012-05-23T06:09:43.117 回答