MySQL-合并并添加缺少的行

时间:2019-01-08 14:42:23

标签: mysql

我有一个带有两个日期列(Date_open和Date_closed)的表。我要做的就是计算每天发生的次数。所以看看每天有多少打开和关闭。我们看了从今天起的最后7天。问题是两列中都没有某些日期,并且我找不到一种方法来链接带有子查询(示例代码1)的表或合并工作(示例代码) 2)

该表如下所示:

+------+------------+-------------+------+
| code | Date_open  | Date_closed | Prio |
+------+------------+-------------+------+
|    1 | 2018-01-08 | 2018-01-08  | A    |
|    2 | 2018-01-01 | 2018-01-08  | B    |
|    3 | 2018-01-06 | 2018-01-07  | C    |
|    4 | 2018-01-06 | 2018-01-06  | A    |
|    5 | 2018-01-04 | 2018-01-06  | B    |
|    6 | 2018-01-03 | 2018-01-01  | C    |
|    7 | 2018-01-03 | 2018-01-02  | C    |
|    8 | 2018-01-03 | 2018-01-02  | C    |
+------+------------+-------------+------+

我想要的结果如下:

Date        OpenNo  CloseNo
2018-01-01     1      1
2018-01-02            2
2018-01-03     3    
2018-01-04     1    
2018-01-05      
2018-01-06     2      2
2018-01-07            1
2018-01-08     1      2

我尝试的第一个代码是:

SELECT *
FROM
(SELECT t1.Date_open,
COUNT(t1.Date_open) AS 'OpenNo'
FROM
Tbl AS t1
GROUP BY t1.Date_open)
AS A
JOIN
(SELECT t2.Date_closed,
COUNT(t2.Date_closed) AS 'CloseNo'
FROM
Tbl AS t2
GROUP BY t2.Date_closed)
AS B ON A.Date_open = B.Date_closed;

只要每天有数据,此代码就起作用。

我尝试的第二个代码是:

SELECT 
  COALESCE (Date_open, Date_closed) AS Date1,
  COUNT(Date_closed) AS ClosedNo, 
  COUNT(Date_open) AS OpenNo

FROM tbl
GROUP BY Date1;

两者都不起作用。有什么想法吗?

下面是创建tbl的代码。

create table Tbl(
        code int(10) primary key,
        Date_open DATE not null,
        Date_closed DATE not null,
    Prio varchar(10));


insert into Tbl values (1,'2018-01-08','2018-01-08' ,'A');
insert into Tbl values (2,'2018-01-01','2018-01-08' ,'B');
insert into Tbl values (3,'2018-01-06','2018-01-07' ,'C');
insert into Tbl values (4,'2018-01-06','2018-01-06' ,'A');
insert into Tbl values (5,'2018-01-04','2018-01-06' ,'B');
insert into Tbl values (6,'2018-01-03','2018-01-01' ,'C');
insert into Tbl values (7,'2018-01-03','2018-01-02' ,'C');
insert into Tbl values (8,'2018-01-03','2018-01-02' ,'C');

2 个答案:

答案 0 :(得分:2)

您可以使用日历表,然后两次与当前表保持连接以生成每个日期的计数:

SELECT
    d.dt,
    COALESCE(t1.open_cnt, 0) AS OpenNo,
    COALESCE(t2.closed_cnt, 0) AS CloseNo
FROM
(
    SELECT '2018-01-01' AS dt UNION ALL
    SELECT '2018-01-02' UNION ALL
    SELECT '2018-01-03' UNION ALL
    SELECT '2018-01-04' UNION ALL
    SELECT '2018-01-05' UNION ALL
    SELECT '2018-01-06' UNION ALL
    SELECT '2018-01-07' UNION ALL
    SELECT '2018-01-08'
) d
LEFT JOIN
(
    SELECT Date_open, COUNT(*) AS open_cnt
    FROM Tbl
    GROUP BY Date_open
) t1
    ON d.dt = t1.Date_open
LEFT JOIN
(
    SELECT Date_closed, COUNT(*) AS closed_cnt
    FROM Tbl
    GROUP BY Date_closed
) t2
    ON d.dt = t2.Date_closed
GROUP BY
    d.dt
ORDER BY
    d.dt;

Demo

之所以将开放日期和结束日期计数汇总在单独的子查询中,是因为如果试图仅对所有涉及的表进行直接联接,我们将不得不处理重复计数。

编辑:

如果您只想使用当前日期和紧接其前的7天,则可以使用CTE:

WITH dates (
    SELECT CURDATE() AS dt UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 1 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 2 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 3 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 4 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 5 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 6 DAY) UNION ALL
    SELECT DATE_SUB(CURDATE(), INTERVAL 7 DAY)
)

您可以将以上内容内联到我的原始查询中,该查询的别名为d,它应该可以工作。

答案 1 :(得分:0)

Coalesce可能令人困惑-它返回您提供给它的列表中的第一个非空值。

我不知道这个问题是否需要一个超级复杂的答案。

要获取每个唯一日期的打开和关闭时间,可以执行以下操作。

SELECT 
  COALESCE (Date_open, Date_closed) AS Date1,
  SUM(IF(Date_closed != null,1,0)) AS ClosedNo, 
  SUM(IF(Date_open != null,1,0)) AS OpenNo

FROM tbl
GROUP BY Date1;
相关问题