2016-09-01 2 views
1

이 데이터 구조로 원하는 결과를 얻을 수 있는지 잘 모르겠습니다. http://sqlfiddle.com/#!9/84939mysql은 각 유형을 행 및 그룹으로 날짜 범위별로 표시합니다.

이것은 기간 데이터를 무시하십시오.

+----+---------------------+---------------------+---------------------+----------+--------+------+ 
| id | created_date  | start_date   | end_date   | duration | status | type | 
+----+---------------------+---------------------+---------------------+----------+--------+------+ 
| 1 | 2016-04-05 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |  30 |  1 | 2 | 
| 2 | 2016-04-06 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |  30 |  1 | 1 | 
| 3 | 2016-04-06 15:23:29 | 2016-08-15 10:21:53 | 2016-08-19 00:00:00 |  30 |  1 | 3 | 
| 4 | 2016-04-06 15:23:29 | 2016-08-17 10:21:53 | 2016-08-19 00:00:00 |  30 |  1 | 1 | 
| 5 | 2016-04-06 15:23:29 | 2016-08-17 09:21:53 | 2016-08-19 00:00:00 |  30 |  1 | 1 | 
| 6 | 2016-04-06 15:23:29 | 2016-08-01 09:21:53 | 2016-08-31 00:00:00 |  30 |  1 | 1 | 
| 7 | 2016-04-06 15:23:29 | 2016-08-01 09:21:53 | 2016-08-31 00:00:00 |  30 |  0 | 1 | 
| 8 | 2016-04-06 15:23:29 | 2016-08-15 09:21:53 | 2016-08-16 00:00:00 |  30 |  1 | 2 | 
| 9 | 2016-04-06 15:23:29 | 2016-08-16 09:21:53 | 2016-08-17 00:00:00 |  30 |  1 | 3 | 
| 10 | 2016-04-06 15:23:29 | 2016-08-19 09:21:53 | 2016-08-20 00:00:00 |  30 |  1 | 2 | 
+----+---------------------+---------------------+---------------------+----------+--------+------+ 

2016-08-15에서 2016-08-19까지 보고서를 필터링하고 싶습니다. 2015-08-19 00:00:00에도 카운트를 고려하지 않았는지 확실하지 않습니다. 하지만 내 예를 들어. 범위에 있기 때문에 계산됩니다. 이 수동으로 나에 의해 수행을 요약 한 것입니다 : -

(type-2)15,16,17,18,19 
(type-1)15,16,17,18,19 
(type-3)15,16,17,18,19 
(type-1)17,18,19 
(type-1)17,18,19 
(type-1)15,16,17,18,19 
(type-1)15,16,17,18,19 
(type-2)15,16 
(type-3)16,17 
(type-2)19,20 

이 내가 SQL 리턴 데이터를 생성하고 싶은 결과이다.

+------------+--------+-----------+-----------+-----------+ 
| date  | ct_all | ct_type_1 | ct_type_2 | ct_type_3 | 
+------------+--------+-----------+-----------+-----------+ 
| 2016-08-15 | 6  | 3   | 2   | 1   | 
| 2016-08-16 | 7  | 3   | 2   | 2   | 
| 2016-08-17 | 8  | 5   | 1   | 2   | 
| 2016-08-18 | 7  | 5   | 1   | 1   | 
| 2016-08-19 | 8  | 5   | 2   | 1   | 
+------------+--------+-----------+-----------+-----------+ 

ct_all =

유형 1에 대한 모든

ct_type_1 = 총 개수만큼 시작일에 입력 낙하를 계산 한 다음 개수 종료일 것이다. 일반적으로 검색 날짜는 한 열 유형 (예 : created_date)의 기준입니다. > =와 < = 사이에서 범위를 찾을 수 있습니다. 하지만이 사람에게는 시작일과 종료일이 있습니다. 확신 할 수 없거나하지 않을 수 있습니다.

+0

모든 기존 날짜가있는 표가 있어야합니다 (예 : [달력 표 : 귀중한 데이터베이스 도구] (http://www.brianshowalter.com/calendar_tables) 참조). '> = start_date'와'<= end_date'에 여러분의 데이터를 연결하십시오. 이것은 당신이 그 때 셀 수 있습니다. – Solarflare

답변

2

세 가지가 있습니다.

  1. 일 수를 열거합니다.
  2. a DATETIME 범위 필터.
  3. 유형별로 행을 열로 피벗하는, 이른바 피벗.

한 번에 하나씩 가져가는 것이 좋습니다.

첫 번째로, 필터링 할 5 일 (2015 년 8 월 15 일 - 2016 년 8 월 20 일)이 필요합니다. 그 모든 요일의 목록을 만들고 싶습니다. 이 작은 쿼리가 그렇게 할 것입니다. (http://sqlfiddle.com/#!9/84939/21/0)

SELECT CONVERT('2016-08-15' + INTERVAL seq DAY, DATETIME) AS CURDATE 
     FROM (SELECT 0 AS SEQ UNION ALL SELECT 1 UNION ALL SELECT 2 
           UNION ALL SELECT 3 UNION ALL SELECT 4 
      ) seq_0_to_4 

가 (뭔가를 주목하라 :. MariaDB fork of MySQLsequence tables like seq_0_to_4 built in은 그래서 당신이 모든 UNION ALL 물건을 할 필요가 없습니다가)

둘째, 당신은에서 발생하는 type 값 목록을 얻으려면 매일. 당신은 LEFT JOIN으로 일어날 수 있습니다. (http://sqlfiddle.com/#!9/84939/26/0).

SELECT seq.curdate, record.type 
    FROM (

      SELECT CONVERT('2016-08-15' + INTERVAL seq DAY, DATETIME) AS CURDATE 
      FROM (SELECT 0 AS SEQ UNION ALL SELECT 1 UNION ALL SELECT 2 
            UNION ALL SELECT 3 UNION ALL SELECT 4 
       ) seq_0_to_4 
     ) seq 
    LEFT JOIN record ON seq.curdate >= DATE(record.start_date) 
        AND seq.curdate <= DATE(record.end_date) 

이렇게하면 curdatetype 값의 목록을 제공합니다.

해당 조인의 조건은 record 행을 각 날짜 또는 그 이전에 시작하여 각 날짜에 언제든지 종료하도록 선택합니다.

마지막으로 입력 값의 수를 요약하려면 pivot 연산을 수행해야합니다. 그것은 이런 모습입니다.(http://sqlfiddle.com/#!9/84939/28/0)

SELECT curdate, 
     COUNT(type) ct_all, 
     SUM(CASE WHEN type = 1 THEN 1 ELSE 0 END) ct_1, 
     SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) ct_2, 
     SUM(CASE WHEN type = 3 THEN 1 ELSE 0 END) ct_3 
    FROM (the above query) d 
    GROUP BY curdate 
    ORDER BY curdate 

이것은 구조화 조회 언어의 구조화 부품이 필요한 경우가있다.

+0

나는 그것을 할 수 있다고 상상할 수 없다. seq_0_to_4 뭔가 새로운 mysql 지식에서 배웁니다. 고맙군 Ollie Jones! 너에게서 굉장한 설명! 감사! – Shiro

관련 문제