SELECT
b.cID,
b.ID,
Count(r.userRead) AS readCount,
COUNT(DISTINCT r.userID) AS UserCount,
Count(c.userDownload) AS downloadCount,
COUNT(DISTINCT c.userID) AS userDownloadCount
FROM
book AS b
INNER JOIN book_event AS r ON r.bookID=s.ID AND r.bookRead = 1
INNER JOIN book_event as c ON c.bookID=s.ID AND c.bookDownload = 1
WHERE
b.cID = 1011
GROUP BY
b.ID
ORDER BY
b.ID DESC
此SQL查询输出(计数问题)
+-----------+-----+-----------+-----------------+--------------+-------------------+
| cID | ID | readCount | UserCount | downloadCount| userDownloadCount |
+-----------+-----+-----------+-----------------+--------------+-------------------+
| 1011 | 278 | 3168 | 67 | 3168 | 19 |
| 1011 | 272 | 9918 | 122 | 9918 | 41 |
| 1011 | 241 | 31694 | 99 | 31694 | 38 |
+-----------+-----+-----------+-----------------+--------------+-------------------+
3 rows in set
实际价值
+-----------+-----+-----------+-----------------+--------------+-------------------+
| cID | ID | readCount | UserCount | downloadCount| userDownloadCount |
+-----------+-----+-----------+-----------------+--------------+-------------------+
| 1011 | 278 | 133 | 67 | 24 | 19 |
| 1011 | 272 | 174 | 122 | 57 | 41 |
| 1011 | 241 | 299 | 99 | 106 | 38 |
+-----------+-----+-----------+-----------------+--------------+-------------------+
book_event(table)
+-----+--------+----------+--------------+
| ID | userID | userRead | userDownload |
+-----+--------+----------+--------------+
| 278 | 5169 | 1 | 0 |
| 278 | 5169 | 0 | 1 |
| ... | .... | . | . |
| 278 | 5628 | 1 | 0 |
| 278 | 5162 | 1 | 0 |
+-----+--------+----------+--------------+
我需要将计数分为两列。 readCount和downloadCount columuns不正确,但UserCount,userDownloadCount columuns值是正确的。
我该如何解决这个问题?
答案 0 :(得分:1)
这是因为您在同一本书上有多个读取和下载事件,因此您的查询会生成事件的交叉产品。
解决此问题的一个好方法是分别汇总信息。但是,您的查询提供了更简单的解决方案只需加入book_event表一次,然后计算不同的事件。
SELECT b.cID, b.ID,
sum(be.bookRead) as readCount,
count(distinct case when be.bookRead = 1 then be.userId end) as UserCount,
sum(be.userDownload) as downloadCount,
count(distinct case when be.userDownload = 1 then be.userId end) as userDownloadCount
FROM book AS b INNER JOIN
book_event be
on be.bookID = s.ID
WHERE b.cID = 1011
GROUP BY b.ID, b.cid
ORDER BY b.ID DESC
我将b.cid添加到group by子句中。在GROUP BY中的SELECT子句中包含所有非聚合值是一种很好的形式。其他数据库强制执行此操作,该规则是标准SQL。
答案 1 :(得分:0)
我认为您的查询在技术上是错误的(按语法分组),但它与您的问题无关并适用于MySQL。
计数问题的最常见原因是没有正确计算空值 - 但我不认为这也是你的问题。
试试这个
SELECT
b.cID,
b.ID,
sum(distinct coalesce(r.userRead,0)) AS readCount,
count(DISTINCT r.userID) AS UserCount,
sum(distinct coalesce(c.userDownload,0)) AS downloadCount,
count(DISTINCT c.userID) AS userDownloadCount
FROM
book AS b
left JOIN book_event AS r ON r.bookID=s.ID AND r.bookRead = 1
left JOIN book_event as c ON c.bookID=s.ID AND c.bookDownload = 1
WHERE
b.cID = 1011
GROUP BY
b.cID, b.ID
ORDER BY
b.ID DESC