2016-01-22 89 views
0

數一些嘗試和一些搜索,我發現,這個查詢給我確切的結果後,我需要:最大重疊日期時間,許多開始和結束時間

SET @start := '2015-12-12 00:00:00', @end := '2015-12-12 23:59:59'; 

SELECT Max(simultaneous_people), 
     Max(simultaneous_event), 
     boundary 
FROM (SELECT Count(id)    AS simultaneous_people, 
       Count(DISTINCT uniqueId) AS simultaneous_event, 
       boundary 
     FROM mytable 
       RIGHT JOIN (SELECT row_begin AS boundary 
          FROM mytable 
          WHERE row_begin BETWEEN @start AND @end 
          UNION 
          SELECT row_end 
          FROM mytable 
          WHERE row_end BETWEEN @start AND @end 
          UNION 
          SELECT @start 
          UNION 
          SELECT @end 
          UNION 
          SELECT Max(boundary) 
          FROM (SELECT Max(row_begin) AS boundary 
            FROM mytable 
            WHERE row_begin <= @start 
            UNION ALL 
            SELECT Max(row_end) 
            FROM mytable 
            WHERE row_end <= @end) t) t 
         ON row_begin <= boundary 
          AND boundary < row_end 
     WHERE row_status = 1 
     GROUP BY boundary) t; 

哪些是重疊的時間的最大數量期間在同一時間。 但我需要這個信息的許多時間間隔之間進行提取,例如10 我無法找出如何與像查詢提取內置的運行時間日曆裏面這樣的信息:

SELECT DATE_SUB(@date, INTERVAL @num MINUTE) AS endSample, 
     DATE_SUB(@date, INTERVAL @num:[email protected][email protected] MINUTE) AS startSample 
FROM 
    mytable, 
    (SELECT @num:=0) num 
LIMIT 10; 

我使用MySQL,很遺憾,我無法在此數據庫上存儲任何數據/表/過程/視圖。

如果有人知道如何以有效的方式合併這兩個查詢將會很好。 謝謝!


更新:

我的架構:

CREATE TABLE mytable (
    id   INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    uniqueId INT, 
    row_status INT, 
    row_begin DATETIME, 
    row_end DATETIME 
); 

而且只是一天的一些數據,以測試只有一小時的粒度:

INSERT INTO mytable (uniqueId, row_status, row_begin, row_end) 
VALUES 
    (1, 1, '2015-12-12 08:00:00', '2015-12-12 12:00:00'), 
    (1, 1, '2015-12-12 08:00:00', '2015-12-12 14:00:00'), 
    (1, 1, '2015-12-12 08:00:00', '2015-12-12 14:00:00'), 
    (2, 1, '2015-12-12 13:00:00', '2015-12-12 14:00:00'), 
    (2, 1, '2015-12-12 13:00:00', '2015-12-12 16:00:00'), 
    (3, 1, '2015-12-12 09:00:00', '2015-12-12 12:00:00'), 
    (3, 0, '2015-12-12 08:00:00', '2015-12-12 16:00:00'); 

我剛剛添加的SQL Fiddle

這裏我必須手動設置每個日期範圍的變量,但我需要能夠設置一個'日曆',並能夠指定日曆是一天一天,一小時一小時還是一分鐘一分鐘,通過調整@length變量。

我的解決方案的第一部分取自this answer

我期望的輸出,以小時爲時間粒度,將是這樣的:

start_sample  | end_sample   | MAX(simultaneous_people) | MAX(simultaneout_event) 
2015-12-12 08:00:00 | 2015-12-12 08:59:59 | 3      | 1 
2015-12-12 09:00:00 | 2015-12-12 09:59:59 | 4      | 2 
2015-12-12 10:00:00 | 2015-12-12 10:59:59 | 4      | 2 
2015-12-12 11:00:00 | 2015-12-12 11:59:59 | 4      | 2 
2015-12-12 12:00:00 | 2015-12-12 12:59:59 | 2      | 1 
2015-12-12 13:00:00 | 2015-12-12 13:59:59 | 4      | 2 
2015-12-12 14:00:00 | 2015-12-12 14:59:59 | 1      | 1 
... 

但是,如果我需要改變粒度天,這個數據,我將獲得

start_sample  | end_sample   | MAX(simultaneous_people) | MAX(simultaneout_event) 
2015-12-12 00:00:00 | 2015-12-12 23:59:59 | 4      | 2 
2015-12-13 00:00:00 | 2015-12-12 23:59:59 | 0      | 0 
... 
+0

包含你的數據庫模式,數據樣本和期望結果。請閱讀http:// stackoverflow。com/help/how-to-ask 這裏是[** START **]的好地方(http://spaghettidba.com/2015/04/24/how-to-post-at-sql-question -on-a-public-forum /) –

+0

如果您願意,可以考慮遵循以下簡單的兩步操作步驟:1.如果您尚未這樣做,請提供適當的CREATE和INSERT語句(和/或sqlfiddle)我們可以更容易地複製問題。 2.如果您尚未這樣做,請提供與步驟1中提供的信息相符的所需結果集。 – Strawberry

+0

@ juan-carlos-oropeza和Strawberry感謝您的建議。我只是添加了CREATE語句和SQL小提琴。 – sabau

回答

0

解決方案比我想象的要容易(希望是正確的,因爲直到現在)。 我會用我的日曆生成器添加一些額外的界限,以避免爲我最終的數據空洞(一天沒有條目不會做出另外的說明):

     ... 
         UNION 
         SELECT @start 
         UNION 
         SELECT @end 
         UNION 
          SELECT DATE_SUB(@date, INTERVAL @num:[email protected][email protected] MINUTE) 
          FROM 
          mytable, 
          (SELECT @num:=0) num 
          LIMIT 10 
         ... 

然後我用得組date_part(在postgres中)或DATE_FORMAT(在MySQL中)對我更有意思(我必須添加一個變量以與@length配對),而不是像以前那樣處理整個邊界,外部查詢將變爲:

SELECT Max(simultaneous_people), 
     Max(simultaneous_event), 
     DATE_FORMAT(boundary,'%Y%m%d') 
FROM (...) as t 
GROUP BY DATE_FORMAT(boundary,'%Y%m%d'); 

我希望這可以幫助別人,它需要一段時間才能達到這一點。 這個查詢對於大量數據來說確實很重,所以越是裁剪/分段(垂直和水平)數據,它的執行效果就越好,應該在任何地方添加'WHERE row_status = 1'工會。

相關問題