Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Nhóm MySQL theo ngày và đếm bao gồm cả những ngày bị thiếu

Bạn cần một OUTER JOIN để đến mỗi ngày từ đầu đến cuối bởi vì nếu bạn sử dụng INNER JOIN nó sẽ giới hạn đầu ra chỉ với những ngày được kết hợp (tức là chỉ những ngày đó trong bảng báo cáo).

Ngoài ra, khi bạn sử dụng OUTER JOIN bạn phải quan tâm đến các điều kiện trong mệnh đề where clause không gây ra implicit inner join; ví dụ AND domain_id =1 nếu sử dụng trong mệnh đề where sẽ loại bỏ bất kỳ hàng nào không đáp ứng điều kiện đó, nhưng khi được sử dụng làm điều kiện nối, nó chỉ hạn chế các hàng của bảng báo cáo.

SELECT
      COUNT(r.domain_id)
    , all_dates.Date AS the_date
    , domain_id
FROM (
        SELECT DATE_ADD(curdate(), INTERVAL 2 MONTH) - INTERVAL (a.a + (10 * b.a) ) DAY as Date
        FROM (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
        CROSS JOIN (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
      ) all_dates
      LEFT OUTER JOIN reports r
                  ON all_dates.Date = r.tracked_on
                        AND domain_id = 1
WHERE all_dates.Date BETWEEN '2014-09-01' AND '2014-09-30'
GROUP BY
      the_date
ORDER BY
      the_date ASC;

Tôi cũng đã thay đổi bảng dẫn xuất all_dates, bằng cách sử dụng DATE_ADD() để thúc đẩy điểm xuất phát trong tương lai, và tôi đã giảm kích thước của nó. Cả hai đều là các tùy chọn và có thể được điều chỉnh khi bạn thấy phù hợp.

Demo tại SQLfiddle

để đến domain_id cho mọi hàng (như được hiển thị trong câu hỏi của bạn), bạn sẽ cần sử dụng một số cách như sau; Lưu ý rằng bạn có thể sử dụng IFNULL() là MySQL cụ thể nhưng tôi đã sử dụng COALESCE() là SQL chung chung hơn. Tuy nhiên, dù sao thì việc sử dụng @parameter như được hiển thị ở đây cũng là dành riêng cho MySQL.

SET @domain := 1;

SELECT
      COUNT(r.domain_id)
    , all_dates.Date AS the_date
    , coalesce(domain_id,@domain) AS domain_id
FROM (
        SELECT DATE_ADD(curdate(), INTERVAL 2 month) - INTERVAL (a.a + (10 * b.a) ) DAY as Date
        FROM (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as a
        CROSS JOIN (select 0 as a union all select 1 union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 union all select 7 union all select 8 union all select 9) as b
      ) all_dates
      LEFT JOIN reports r
                  ON all_dates.Date = r.tracked_on
                        AND domain_id = @domain
WHERE all_dates.Date BETWEEN '2014-09-01' AND '2014-09-30'
GROUP BY
      the_date
ORDER BY
      the_date ASC;

Xem phần này tại SQLfiddle



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Lưu trữ dữ liệu của hộp văn bản đa dạng thức vào cơ sở dữ liệu với định dạng

  2. Cách đọc và đặt lại AUTO_INCREMENT trong MySQL

  3. Hiểu lỗi đơn giản trong MySQL

  4. Làm cách nào để thay đổi Đối chiếu cột mà không làm mất hoặc thay đổi dữ liệu?

  5. DISTINCT ON trong django