2014-10-10 2 views
2

내 문제를 해결하기 위해 SQL 쿼리를 만들려고합니다.
일별 및 시간별 그룹 MySql 쿼리

내 테이블 :

+----+---------------------+-------+ 
| id |   date  | value | 
+----+---------------------+-------+ 
| 1 | 2014-10-10 05:10:10 | 10 | 
+----+---------------------+-------+ 
| 2 | 2014-10-10 09:10:10 | 20 | 
+----+---------------------+-------+ 
| 3 | 2014-10-10 15:10:10 | 30 | 
+----+---------------------+-------+ 
| 4 | 2014-10-10 23:10:10 | 40 | 
+----+---------------------+-------+ 
| 5 | 2014-10-11 08:10:10 | 15 | 
+----+---------------------+-------+ 
| 6 | 2014-10-11 09:10:10 | 25 | 
+----+---------------------+-------+ 
| 7 | 2014-10-11 10:10:10 | 30 | 
+----+---------------------+-------+ 
| 8 | 2014-10-11 23:10:10 | 40 | 
+----+---------------------+-------+ 
내가 일까지 그룹의 값을 합계를

과 '아침'과 같은 세 개의 하위 그룹에서이 일 (6시에서 12시까지), '오후'(12:00 - 18:00) 및 '밤'(00:00 - 06:00 및 18:00 - 24:00)입니다. 이 같은
무엇인가 : 당신은 case 표현을 통해 sum의 몇 가지를 사용할 수

+------------+-------+---------+-----------+-------+ 
| date | value | morning | afternoon | night | 
+------------+-------+---------+-----------+-------+ 
| 2014-10-10 | 100 | 20 |  30 | 50 | 
+------------+-------+---------+-----------+-------+ 
| 2014-10-11 | 110 | 70 |  0  | 40 | 
+------------+-------+---------+-----------+-------+ 

답변

1

:

SELECT DAY(`date`) AS `date` 
     SUM(CASE WHEN HOUR(`date`) BETWEEN 6 AND 12 THEN value ELSE 0 END) AS `morning`, 
     SUM(CASE WHEN HOUR(`date`) BETWEEN 12 AND 18 THEN value ELSE 0 END) AS `afternoon`, 
     SUM(CASE WHEN HOUR(`date`) < 6 OR HOUR(`date`) > 18 THEN value ELSE 0 END) AS `evening` 
FROM  my_table 
GROUP BY DAY(`date`) 
+0

은 대단히 감사합니다! 그것은 아주 잘 작동했습니다. –

0

이 이것에 대해 갈 수있는 여러 가지 방법이 있지만, 자신을 위해 내가 할 것 CROSS APPLY의 의사 정보를 먼저 추출한 다음이 정보를 그룹화합니다.

나는 이것이 상당한 가독성 이점을 제공하며 다른 절에서 계산을 재사용 할 수 있다고 생각합니다. 예를 들어 그룹화 메커니즘을 중앙 집중화 했으므로 선택 및 그룹화 기준이 아닌 한 위치에서만 변경해야합니다. 마찬가지로 아침에 계산을 다시 쓰는 대신 WHERE 절에 "extraData.Morning = 1"을 추가 할 수 있습니다. 예를 들어

:

CREATE TABLE #TestData (ID INT, Data DATETIME, Value INT) 

INSERT INTO #TestData (ID, Data, Value) VALUES 
    (1 ,'2014-10-10 05:10:10' ,10) 
    ,(2 ,'2014-10-10 09:10:10' ,20) 
    ,(3 ,'2014-10-10 15:10:10' ,30) 
    ,(4 ,'2014-10-10 23:10:10' ,40) 
    ,(5 ,'2014-10-11 08:10:10' ,15) 
    ,(6 ,'2014-10-11 09:10:10' ,25) 
    ,(7 ,'2014-10-11 10:10:10' ,30) 
    ,(8 ,'2014-10-11 23:10:10' ,40) 

SELECT 
    extraData.DayComponent 
    ,SUM(td.Value) 
    ,SUM(CASE WHEN extraData.Morning = 1 THEN td.Value ELSE 0 END) AS Morning 
    ,SUM(CASE WHEN extraData.Afternoon = 1 THEN td.Value ELSE 0 END) AS Afternoon 
    ,SUM(CASE WHEN extraData.Night = 1 THEN td.Value ELSE 0 END) AS Night 
FROM #TestData td 
    CROSS APPLY (
     SELECT 
      DATEADD(dd, 0, DATEDIFF(dd, 0, td.Data))  AS DayComponent 
      ,CASE WHEN DATEPART(HOUR, td.Data) BETWEEN 6 AND 12 THEN 1 ELSE 0 END AS Morning 
      ,CASE WHEN DATEPART(HOUR, td.Data) BETWEEN 12 AND 18 THEN 1 ELSE 0 END AS Afternoon 
      ,CASE WHEN DATEPART(HOUR, td.Data) BETWEEN 0 AND 6 
       OR DATEPART(HOUR, td.Data) BETWEEN 18 AND 24 THEN 1 ELSE 0 END AS Night 
    ) extraData 
GROUP BY 
    extraData.DayComponent 

DROP TABLE #TestData 
+0

크로스 적용은 SQL Server 전용입니까? –

+0

아, 제 사과는 mySQL 태그를 알아 채지 못했습니다. 테이블 서식에서 힌트를 얻었습니다. – mrmillsy