【问题标题】:Get count on two different date columns and group by date获取两个不同日期列的计数并按日期分组
【发布时间】:2013-11-05 23:08:41
【问题描述】:

我有一个包含两个 DATE 列的表。 TS_customer 和 TS_verified

我正在寻找一种方法来获得结果,在第一列中我有日期,其中有人创建了用户 (TS_customer) 或有人得到了验证 (TS_verified)。

在第二列中,我希望 count(TS_customer) 按第一列分组。 第三列我要count(TS_verified)按第一列分组。

可能有 0 个客户在注册日期得到验证,在另一种情况下,在某人得到验证的日期有 0 个注册。

我想这应该很容易,但我现在已经花了很多时间。非常感谢一些帮助。我需要这个用于 excel 中的图表,所以我基本上希望一天有多少客户注册以及有多少得到验证,而不必麻烦地进行两次选择并手动组合它们。

编辑:链接到 SQLfiddle http://sqlfiddle.com/#!2/b14fc/1/0

谢谢

【问题讨论】:

  • 建议你用数据创建一个 sql fiddle...
  • 因为你是新来的!这是您知道在哪里做的链接:sqlfiddle.com 在那里您可以创建一个表并插入一些示例数据,以便我们更好地了解您的问题。
  • 谢谢!我真的不知道如何以更合适的方式导出它,但我会四处寻找。这是链接sqlfiddle.com/#!2/b14fc/1/0
  • 你写“在我想要的结果集的第一列中,TS_customer 和 TS_verified 的不同日期”。您是说要显示两个日期吗?我不认为你是,但不是很清楚。
  • Ollie:我只需要我想要的结果集的第一列中的日期。这些日期来自哪里,我认为如果我能从某人注册或验证他们的帐户的地方知道这些日期会很好

标签: mysql sql count group-by


【解决方案1】:

首先,我们需要日期列表。

看起来像这样http://sqlfiddle.com/#!2/b14fc/14/0:

   SELECT DISTINCT days
     FROM (
       SELECT DISTINCT DATE(TS_customer) days
         FROM customer
        UNION 
       SELECT DISTINCT DATE(TS_verified) days
         FROM customer

     ) AS alldays
 WHERE days IS NOT NULL
 ORDER BY days

接下来,我们需要按天汇总客户数量。这很简单http://sqlfiddle.com/#!2/b14fc/16/0:

SELECT DATE(TS_customer) days, COUNT(TS_customer)
  FROM customer
 GROUP BY days

每天的验证摘要同样简单。

接下来我们需要将这三个子查询连接在一起http://sqlfiddle.com/#!2/b14fc/29/0

SELECT alldays.days, custcount, verifycount
  FROM (
           SELECT DISTINCT DATE(TS_customer) days
             FROM customer
            UNION 
           SELECT DISTINCT DATE(TS_verified) days
             FROM customer
       ) AS alldays
   LEFT JOIN (
      SELECT DATE(TS_customer) days, COUNT(TS_customer) custcount
        FROM customer
       GROUP BY days
      ) AS cust ON alldays.days = cust.days
   LEFT JOIN (
      SELECT DATE(TS_verified) days, COUNT(TS_verified) verifycount
        FROM customer
       GROUP BY days
      ) AS verif ON alldays.days = verif.days
  WHERE alldays.days IS NOT NULL
  ORDER BY alldays.days

最后,如果您希望在没有任何客户和/或验证的日子里显示 0 而不是 (null),请将 SELECT 行更改为此 http://sqlfiddle.com/#!2/b14fc/30/0

SELECT alldays.days, 
       IFNULL(custcount,0) AS custcount, 
       IFNULL(verifycount,0) AS verifycount

看看情况如何?我们逐步建立您的结果集。

【讨论】:

  • 谢谢,效果很好!我走在正确的道路上,用三个不同的集合构建它们并将它们组合起来,(​​使用联合和两个正常选择)但计数总是对我来说一团糟。得到了总计数值的 3 倍,在某些行中达到了 6 倍。
  • 好的,不客气。需要一段时间才能弄清楚您必须在加入之前进行汇总,否则计数将是错误的。
【解决方案2】:

我有点困惑,为什么您在 TS_Customer 上创建了一个不能保存 null 值的小提琴,然后提到该字段可以保存 null 值。

话虽如此,我已经修改了解决方案以使用 null 值,并且仍然非常高效和简单:

SELECT days, sum(custCount) custCount, sum(verifCount) verifCount FROM (
  SELECT DATE(TS_customer) days, count(*) custCount, 0 verifCount
  FROM customer
  WHERE TS_customer IS NOT NULL
  GROUP BY days
  UNION ALL
  SELECT DATE(TS_verified) days, 0, count(*)
  FROM customer
  WHERE TS_verified IS NOT NULL
  GROUP BY days
) s
GROUP BY days

我还创建了一个不同的小提琴,其中包含一些空值here

【讨论】:

  • 我没有让这个工作。当某人在没有新客户重新开始的日期得到验证时,TS_Customer 中可能有空值。我在顶部选择中添加了 WHERE TS_customer IS NOT NULL,但左列(日期列)中有重复的日期
  • 你是对的,它没有正确处理空值,但我没有测试它,因为你的小提琴不允许该列上有空值:) 无论如何,我提供了一个新的(不像以前那么快)解决方案,可以处理那些空值
猜你喜欢
  • 2019-04-22
  • 1970-01-01
  • 2016-01-03
  • 2016-11-24
  • 2013-01-07
  • 2020-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多