7

数据库结构

CREATE TABLE installs(
    id INT, PRIMARY KEY(id), 
    created DATETIME)

CREATE TABLE uninstalls(
    id INT, PRIMARY KEY(id),
    created DATETIME,
    install_id INT)

查询(“我与 MySQL”)

SELECT DATE(installs.created),
  COUNT(installs.id),
  COUNT(uninstall.id)
FROM installs
LEFT JOIN uninstalls ON uninstalls.install_id = installs.id
GROUP BY DATE(installs.created)

“预期”输出

DATE(installs.created) | COUNT(installs.id) | COUNT(uninstalls.id) 
  2012-11-20           | *installs on date* | *uninstalls on date*

所以 - 我每天都在查看当天发生的安装/卸载次数。

问题

每天的“安装”数据都是正确的。但遗憾的是,每天“卸载”的数据不正确。

4

3 回答 3

4

Count the installs and the uninstall separately, adding a column (of zeroes) for the other count to each of them. Then combine the two with UNION, group by date once again and take the max for each date (to eliminate the added zeroes):

SELECT created as date, max(installs) as installs, max(uninstalls) as uninstalls
FROM
  (SELECT created, count(*) AS installs, 0 AS uninstalls
   FROM installs
   GROUP BY created
  UNION ALL
   SELECT created, 0 AS installs, count(*) AS uninstalls
   FROM uninstalls
   GROUP BY created) c
GROUP BY created
ORDER BY created
于 2012-11-21T23:19:44.217 回答
0

发生此问题是因为您正在链接安装和卸载。也就是说,您显示的是给定日期的安装,以及这些安装的卸载,而不是安装日期。

如果您想查看给定日期的每个事件的计数,您需要在date加入,而不是安装 ID。如果它是一个大型数据集,它会非常慢(当您根据该字段上的函数分组或连接时,优化器不能在该字段上使用索引)。

SELECT DATE(installs.created),
  COUNT(installs.id),
  COUNT(uninstall.id)
FROM installs 
LEFT JOIN uninstalls ON DATE(uninstalls.created) = DATE(installs.created)
GROUP BY DATE(installs.created)
于 2012-11-21T17:52:59.957 回答
0

创建一个包含所有安装和卸载日期的 CTE,然后分别加入安装和卸载表。

; WITH Dates AS
(
    SELECT DATE(created) AS created
    FROM
    (
        SELECT created
        FROM installs

            UNION ALL

        SELECT created
        FROM uninstalls
    ) a
    GROUP BY DATE(created)
)
, InstallCTE AS
(
    SELECT DATE(created) AS created
        , COUNT(*) AS c
    FROM installs
    GROUP BY DATE(created)
)
, UninstallCTE AS
(
    SELECT DATE(created) AS created
        , COUNT(*) AS c
    FROM uninstalls
    GROUP BY DATE(created)
)
SELECT d.created AS [date]
    , i.c AS install_count
    , u.c AS uninstall_count
FROM Dates d
LEFT JOIN InstallCTE i
    ON d.created = i.created
LEFT JOIN UninstallCTE u
    ON d.created = u.created
于 2012-11-21T20:43:20.683 回答