mysql - 如何仅针对我输入的日期返回自连接查询的结果?

标签 mysql self-join

<分区>

我需要一群活跃用户。 1天/7天/14天/28天。与谷歌分析相同。我似乎无法理解所需的查询。

我知道我需要进行自连接,但我只能做到这一点。

我有这个查询,但它产生了错误的结果。

SELECT
    DATE(logins.logged_in_at) AS `date`,
    logins.company_id,
    SUM(IF(d1.logged_in_at, 1, 0)) AS d1,
    SUM(IF(d7.logged_in_at, 1, 0)) AS d7,
    SUM(IF(d14.logged_in_at, 1, 0)) AS d14,
    SUM(IF(d28.logged_in_at, 1, 0)) AS d28
FROM logins
LEFT JOIN logins AS d1
    ON DATE(logins.logged_in_at) = (DATE(d1.logged_in_at) - INTERVAL 1 DAY)
LEFT JOIN logins AS d7
    ON DATE(logins.logged_in_at) = (DATE(d7.logged_in_at) - INTERVAL 7 DAY)
LEFT JOIN logins AS d14
    ON DATE(logins.logged_in_at) = (DATE(d14.logged_in_at) - INTERVAL 14 DAY)
LEFT JOIN logins AS d28
    ON DATE(logins.logged_in_at) = (DATE(d28.logged_in_at) - INTERVAL 28 DAY)
GROUP BY
    DATE(logins.logged_in_at),
    logins.company_id
ORDER BY
    logins.logged_in_at;

+------------+------------+----+----+-----+-----+
|    date    | company_id | d1 | d7 | d14 | d28 |
+------------+------------+----+----+-----+-----+
| 2019-01-01 |          1 |  8 |  8 |   8 |   8 |
| 2019-01-02 |          1 |  2 |  2 |   2 |   0 |
| 2019-01-03 |          1 |  2 |  2 |   2 |   0 |
| 2019-01-04 |          1 |  2 |  2 |   2 |   0 |
| 2019-01-05 |          1 |  2 |  2 |   2 |   0 |
| 2019-01-06 |          1 |  2 |  2 |   2 |   0 |
| 2019-01-07 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-08 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-09 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-10 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-11 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-12 |          1 |  6 |  6 |   6 |   0 |
| 2019-01-13 |          1 | 12 | 12 |  12 |   0 |
| 2019-01-14 |          1 | 48 | 48 |  48 |   0 |
| 2019-01-15 |          1 | 48 | 48 |  48 |   0 |
| 2019-01-16 |          1 | 12 | 12 |   0 |   0 |
| 2019-01-17 |          1 | 12 | 12 |   0 |   0 |
| 2019-01-18 |          1 | 12 | 12 |   0 |   0 |
| 2019-01-19 |          1 | 12 | 12 |   0 |   0 |
| 2019-01-20 |          1 | 18 | 18 |   0 |   0 |
| 2019-01-21 |          1 | 36 | 36 |   0 |   0 |
| 2019-01-22 |          1 | 36 | 36 |   0 |   0 |
| 2019-01-23 |          1 |  9 |  0 |   0 |   0 |
| 2019-01-24 |          1 |  9 |  0 |   0 |   0 |
| 2019-01-25 |          1 |  9 |  0 |   0 |   0 |
| 2019-01-26 |          1 |  9 |  0 |   0 |   0 |
| 2019-01-27 |          1 | 12 |  0 |   0 |   0 |
| 2019-01-28 |          1 | 16 |  0 |   0 |   0 |
| 2019-01-29 |          1 |  0 |  0 |   0 |   0 |
+------------+------------+----+----+-----+-----+

表结构和示例数据如下:

CREATE TABLE `logins` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `company_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `logged_in_at` timestamp NOT NULL,
  PRIMARY KEY (`id`),
  KEY `logins_company_id_index` (`company_id`),
  KEY `logins_user_id_index` (`user_id`),
  KEY `logins_logged_in_at_index` (`logged_in_at`)
) ENGINE=InnoDB AUTO_INCREMENT=57 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

INSERT INTO `logins` (`id`, `company_id`, `user_id`, `logged_in_at`)
VALUES
    (1, 1, 1, '2019-01-01 00:00:00'),
    (2, 1, 1, '2019-01-02 00:00:00'),
    (3, 1, 1, '2019-01-03 00:00:00'),
    (4, 1, 1, '2019-01-04 00:00:00'),
    (5, 1, 1, '2019-01-05 00:00:00'),
    (6, 1, 1, '2019-01-06 00:00:00'),
    (7, 1, 1, '2019-01-07 00:00:00'),
    (8, 1, 1, '2019-01-08 00:00:00'),
    (9, 1, 1, '2019-01-09 00:00:00'),
    (10, 1, 1, '2019-01-10 00:00:00'),
    (11, 1, 1, '2019-01-11 00:00:00'),
    (12, 1, 1, '2019-01-12 00:00:00'),
    (13, 1, 1, '2019-01-13 00:00:00'),
    (14, 1, 1, '2019-01-14 00:00:00'),
    (15, 1, 1, '2019-01-15 00:00:00'),
    (16, 1, 1, '2019-01-16 00:00:00'),
    (17, 1, 1, '2019-01-17 00:00:00'),
    (18, 1, 1, '2019-01-18 00:00:00'),
    (19, 1, 1, '2019-01-19 00:00:00'),
    (20, 1, 1, '2019-01-20 00:00:00'),
    (21, 1, 1, '2019-01-21 00:00:00'),
    (22, 1, 1, '2019-01-22 00:00:00'),
    (23, 1, 1, '2019-01-23 00:00:00'),
    (24, 1, 1, '2019-01-24 00:00:00'),
    (25, 1, 1, '2019-01-25 00:00:00'),
    (26, 1, 1, '2019-01-26 00:00:00'),
    (27, 1, 1, '2019-01-27 00:00:00'),
    (28, 1, 1, '2019-01-28 00:00:00'),
    (29, 1, 1, '2019-01-29 00:00:00'),
    (30, 1, 2, '2019-01-14 00:00:00'),
    (31, 1, 2, '2019-01-15 00:00:00'),
    (32, 1, 2, '2019-01-16 00:00:00'),
    (33, 1, 2, '2019-01-17 00:00:00'),
    (34, 1, 2, '2019-01-18 00:00:00'),
    (35, 1, 2, '2019-01-19 00:00:00'),
    (36, 1, 2, '2019-01-20 00:00:00'),
    (37, 1, 2, '2019-01-21 00:00:00'),
    (38, 1, 2, '2019-01-22 00:00:00'),
    (39, 1, 2, '2019-01-23 00:00:00'),
    (40, 1, 2, '2019-01-24 00:00:00'),
    (41, 1, 2, '2019-01-25 00:00:00'),
    (42, 1, 2, '2019-01-26 00:00:00'),
    (43, 1, 2, '2019-01-27 00:00:00'),
    (44, 1, 2, '2019-01-28 00:00:00'),
    (45, 1, 2, '2019-01-29 00:00:00'),
    (46, 1, 3, '2019-01-21 00:00:00'),
    (47, 1, 3, '2019-01-22 00:00:00'),
    (48, 1, 3, '2019-01-23 00:00:00'),
    (49, 1, 3, '2019-01-24 00:00:00'),
    (50, 1, 3, '2019-01-25 00:00:00'),
    (51, 1, 3, '2019-01-26 00:00:00'),
    (52, 1, 3, '2019-01-27 00:00:00'),
    (53, 1, 3, '2019-01-28 00:00:00'),
    (54, 1, 3, '2019-01-29 00:00:00'),
    (55, 1, 4, '2019-01-28 00:00:00'),
    (56, 1, 4, '2019-01-29 00:00:00');

如果我在 2019-01-29 上运行所需的查询,我希望得到这样的结果:

+------------+------------+----+----+-----+-----+
| company_id |    date    | d1 | d7 | d14 | d28 |
+------------+------------+----+----+-----+-----+
|          1 | 2019-01-29 |  4 |  3 |   2 |   1 |
+------------+------------+----+----+-----+-----+

如果您需要更多信息,请告诉我

最佳答案

仅因为此查询生成相同的结果,我认为这就是您所追求的...

SELECT company_id
     , date
     , SUM(d1) d1
     , SUM(d7) d7
     , SUM(d14) d14
     , SUM(d28) d28
  FROM 
     ( SELECT DISTINCT x.logged_in_at date
                     , x.company_id
                     , y.user_id
                     , y.logged_in_at = x.logged_in_at - INTERVAL   1 DAY d1 
                     , y.logged_in_at = x.logged_in_at - INTERVAL   7 DAY d7
                     , y.logged_in_at = x.logged_in_at - INTERVAL  14 DAY d14 
                     , y.logged_in_at = x.logged_in_at - INTERVAL  28 DAY d28 

                  FROM logins x 
                  JOIN logins y 
                    ON y.company_id = x.company_id
                   AND y.logged_in_at < x.logged_in_at 
                 WHERE x.logged_in_at = '2019-01-29'
     ) a
 GROUP
    BY company_id
     , date;

关于mysql - 如何仅针对我输入的日期返回自连接查询的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54553737/

相关文章:

mySQL将同一列中的两个值相除

sql - 自连接查询

php - Laravel 自连接查询

mysql - 如何在相关表中添加子行? (Sequelzie N :M Relationship)

mysql - 如何用 JOIN 替换 NOT EXISTS?

mysql - SQL 并排显示来自不同表的两列数据,无需连接

sql - 显示指向同一个表的两个 id 字段的两个链接值

mysql - 为什么在mysql中布局股票表的最佳理由是什么?

mysql - 如何为动态字段创建mysql数据库表

sql - 如何删除SQL Server自连接中的重复行