Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql SQL联接和跨三个表的计数_Mysql_Join_Multiple Tables - Fatal编程技术网

Mysql SQL联接和跨三个表的计数

Mysql SQL联接和跨三个表的计数,mysql,join,multiple-tables,Mysql,Join,Multiple Tables,我有三个表,其中包含以下相关列 产品名称:ProductID 审阅:ReviewID、ProductID、UserID 用户:UserId,StateID 并非所有产品都有评论,但所有评论都有一个产品和一个用户 我编写了一个查询,返回所有产品详细信息加上一个审核计数,这是可行的。现在我想限制评论计数,这样它只包括用户状态为1的评论(例如未删除/禁止)。这就是我所拥有的,但不太管用 SELECT product.*, count(r.ProductId) as reviewCount, u.s

我有三个表,其中包含以下相关列

  • 产品名称:ProductID
  • 审阅:ReviewID、ProductID、UserID
  • 用户:UserId,StateID
并非所有产品都有评论,但所有评论都有一个产品和一个用户

我编写了一个查询,返回所有产品详细信息加上一个审核计数,这是可行的。现在我想限制评论计数,这样它只包括用户状态为1的评论(例如未删除/禁止)。这就是我所拥有的,但不太管用

SELECT product.*, count(r.ProductId) as reviewCount, u.state
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
LEFT OUTER JOIN Users u ON u.userId = r.userId AND u.state IN (1)
GROUP BY p.id
计数仍然包括用户状态为2的评论。谁能看出我做错了什么?很明显,我对SQL不是那么在行

进行计数的工作SQL如下所示

SELECT product.*, count(r.ProductId) as reviewCount
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
GROUP BY p.id
下面是一些示例表的DDL。它创建了三辆车(car1、car2、car3),为car1添加了三条评论,为car2添加了一条评论,但其中一个为car2进行评论的用户的状态为1(即忽略):

因此,结果应该是:

ProductID    name    reviewCount
        1    car1              2
        2    car2              1
        3    car3              0
试着简单一点

SELECT _p.*, count(_r.ProductID) as reviewCount, _u.stat
FROM Product _p 
INNER JOIN Review _r ON _r.ProductID = _p.ProductID
INNER JOIN User  _u ON _u.UserID = _r.UserID AND _u.StateID = 1;  
GROUP BY _p.ProductID

你要计算评论。因此,计数
ReviewId
,而不是
ProductId
。您的
u.state
不在
where
子句中。试试这个:

SELECT p.*, count(r.ReviewId) as reviewCount
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
LEFT OUTER JOIN Users u ON u.userId = r.userId
WHERE u.state = 1
GROUP BY p.id;
编辑

如果您尝试这样一个简单而沉重的请求,会发生什么

SELECT ProductId, ProductName, count(ReviewId) as reviewCount
FROM Product p, Review r, User u
WHERE p.ProductId = r.ProductId AND r.UserId = u.UserId AND u.state = 1
GROUP BY p.ProductID;

下面的查询不起作用,因为您将join留给了用户,这意味着如果相关用户处于状态2,您仍将看到他们的审阅,只是用户的相关字段为null(您可能会看到用户处于状态2的行的u.state为null)

您可以更改查询以删除u.state上的谓词,并将查询中的计数替换为CASE语句的总和,对于有效的用户评论,CASE求值为1,对于othersm求值为0,如下所示:

SELECT product.*, SUM(CASE WHEN u.state NOT IN (1) THEN 1 ELSE 0 END) AS reviewCount
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
LEFT JOIN Users u ON u.userId = r.userId
GROUP BY p.id

我已经用您之前提供的测试用例尝试过了,添加了一个无效用户对car3的评论,效果很好。

Count(或者更确切地说SUM)有些不同。草莓-我尝试了p.id和r.id的SUM和Count,但没有任何区别。耳机id来自哪里?抱歉,这是我的另一个表。我将该示例设置为通用示例,以使其更简单。现在应该修好了。不幸的是,这似乎不起作用。当我这样做的时候,一些产品根本就不会被退回。但我仍然不明白为什么你们两个都在计算
r.ProductId
而不是
r.ReviewId
@Kabulan0lak:计算被审查的产品的好处是——我们已经编辑了答案,考虑到这一点,我认为我们正在接近,但不是很接近。我在上面添加了一些DDL来创建数据库、表和数据,因此我们有一个精确的定义来处理。审查计数结果不正确(显示1对car1的审查,应该是2),并且一个没有审查的产品没有显示(car3)。Tom-当我更改查询以匹配表定义时(您更改了一些列名),并更改where子句以查找状态2而不是1(您最初说需要状态1,但从insert语句中,我看到这是您不想要的状态),我得到产品1的reviewcount为2,产品2的reviewcount为1,产品3的reviewcount为0。我将编辑我的答案,以便您对所需的用户状态进行新的解释,但我认为它会满足您的需要。您是对的!很抱歉,我在更改时一定输入了错误。谢谢,问题已解决!花一点时间,我甚至可能会理解它的工作原理!谢谢你的解释,我会在早上读到:)这也不行:(我在上面添加了DDL,所以我们有一个精确的表/数据要处理。在那个例子中,我最后告诉我我有一次对car1的审阅,而不是2;car2和car3根本没有出现。正如@mc110所说,您希望state=2而不是state=1!现在返回一个结果是合理的-car1的审阅计数为1。怀疑我们需要某种outer加入,因为没有对car3的评论。不过,感谢您的额外建议。仅供参考,我将在大约9小时后(早上)再次拿起这个。不太清楚-car3没有出现,可能是因为没有评论。我怀疑有必要进行外部加入。不过,感谢您的努力:)
SELECT product.*, count(r.ProductId) as reviewCount, u.state
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
LEFT OUTER JOIN Users u ON u.userId = r.userId AND u.state IN (1)
GROUP BY p.id
SELECT product.*, SUM(CASE WHEN u.state NOT IN (1) THEN 1 ELSE 0 END) AS reviewCount
FROM Product p
LEFT OUTER JOIN Review r ON p.id = r.ProductId
LEFT JOIN Users u ON u.userId = r.userId
GROUP BY p.id