2016-01-24 66 views
0

我有表:的MySQL 5.6:GROUP_CONCAT幫助尋求

CREATE TABLE IF NOT EXISTS `buildingAccess` (
    `id` int(10) unsigned NOT NULL, 
     `building` varchar(16) NOT NULL, 
     `person` varchar(16) NOT NULL, 
     `enteryDate` datetime NOT NULL, 
     `exitDate` datetime DEFAULT NULL 
    ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8; 

    INSERT INTO `buildingAccess` (`id`, `building`, `person`, `enteryDate`, `exitDate`) VALUES 
    (1, 'Lot B-3', 'Alice Jones', '2015-11-10 05:29:14', '2015-11-10 15:18:42'), 
    (3, 'Lot B-3', 'Alice Jones', '2015-11-11 07:11:27', '2015-11-11 12:43:34'), 
    (7, 'Lot B-3', 'Alice Jones', '2015-12-10 07:11:27', '2015-12-11 12:43:34'), 
    (2, 'Lot B-3', 'Bill Mayhew', '2015-11-10 10:29:14', '2015-11-10 12:18:42'), 
    (4, 'Lot B-3', 'Bill Mayhew', '2015-11-12 09:10:27', '2015-11-13 02:43:34'), 
    (8, 'Lot B-3', 'Bill Mayhew', '2015-11-12 09:10:27', '2015-11-13 02:43:34'), 
    (5, 'Lot B-3', 'Charlotte Ahn', '2015-12-01 05:29:14', NULL), 
    (6, 'Lot B-3', 'Dennis Lowe', '2015-12-10 10:29:14', '2015-12-10 12:18:42'); 

    CREATE TABLE IF NOT EXISTS `buildingNotes` (
     `building` varchar(16) NOT NULL, 
     `observer` varchar(16) NOT NULL, 
     `observationDate` datetime NOT NULL, 
     `note` varchar(64) NOT NULL 
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8; 

    INSERT INTO `buildingNotes` (`building`, `observer`, `observationDate`, `note`) VALUES 
    ('Lot B-3', 'Alice Jones', '2015-11-10 05:32:12', 'burned out light on pole South-22'), 
    ('Lot B-3', 'Alice Jones', '2015-11-10 05:39:12', 'burned out light on pole West-7'), 
    ('Lot B-3', 'Alice Jones', '2015-11-10 05:42:12', 'overfull trash can near pole North-11'), 
    ('Lot B-3', 'Charlotte Ahn', '2015-12-01 06:09:14', 'change drawr running low at gate 3'); 

    ALTER TABLE `buildingAccess` 
    ADD PRIMARY KEY (`id`), ADD KEY `building` (`building`,`person`,`enteryDate`,`exitDate`); 

    ALTER TABLE `buildingNotes` 
    ADD KEY `building` (`building`,`observer`,`observationDate`,`note`); 

    ALTER TABLE `buildingAccess` 
    MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=9; 

我的目標是返回在buildingAccess表中的所有記錄列表的查詢。每個應該有一個notes字段,即buildingAccess.enteryDatebuildingAccess.exitDate括起來的記錄日期/時間中所有buildingNotes.note條目的GROUP_CONCAT

我已經嘗試了一些東西,但我堅持在:

select 
     BA.building, 
     BA.person, 
     BA.enteryDate, 
     IFNULL(BA.exitDate, NOW()), 
     IFNULL(
      GROUP_CONCAT(
       '<p>', 
       BN.observationDate, ': ', 
       BN.observer, ': ', BN.note, 
       '</p>' 
       ORDER BY BN.observationDate ASC 
       SEPARATOR '' 
      ), 
      '' 
     ) 
    from 
     buildingAccess BA 
     LEFT JOIN buildingNotes BN ON 
      BN.building = BA.building 
      AND BN.observationDate BETWEEN BA.enteryDate AND BA.exitDate 
    group by BN.building 

這將返回:

+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| building | person  | enteryDate   | exitDate   | observations                                                      | 
+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 
| Lot B-3 | Charlotte Ahn | 2015-12-01 05:29:14 | 2016-01-23 23:04:04 |                                                         | 
| Lot B-3 | Alice Jones | 2015-11-10 05:29:14 | 2015-11-10 15:18:42 | <p>2015-11-10 05:32:12: Alice Jones: burned out light on pole South-22</p><p>2015-11-10 05:39:12: Alice Jones: burned out light on pole West-7</p><p>2015-11-10 05:42:12: Alice Jones: overfull trash can near pole North-11</p> | 
+----------+---------------+---------------------+---------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 

我希望看到所有的其他buildingAccess記錄,即使沒有buildingNotes記錄。

我假設我不是「按組合」的正確的東西,但我還沒有找到正確的組合。

指針?

+0

您可以添加whta作爲您當前數據集示例的理想結果嗎? –

+1

請閱讀https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html所謂的* extension *到GROUP BY的MySQL給你的印象是你只能使用一列的ref group by子句,但在select子句中有更多非聚合列。這是假的,結果可能是假的,嘗試你的查詢,但這次** GROUP BY BA.building,BA.person,BA.enteryDate **注意到BA.building的變化 –

回答

1

我相信這是由於使用來自GROUP BY子句中外連接表的BN.building。請嘗試以下操作:

SELECT 
     BA.building 
    , BA.person 
    , BA.enteryDate 
    , IFNULL(BA.exitDate, NOW()) 
    , IFNULL (
       GROUP_CONCAT (
          '<p>', 
          BN.observationDate, ': ', 
          BN.observer, ': ', BN.note, 
          '</p>' 
          ORDER BY BN.observationDate ASC 
          SEPARATOR '' 
          ) 
       ,'' 
      ) 
FROM buildingAccess BA 
     LEFT JOIN buildingNotes BN ON BN.building = BA.building 
        AND BN.observationDate BETWEEN BA.enteryDate AND BA.exitDate 
GROUP BY 
     BA.building 
    , BA.person 
    , BA.enteryDate 
    , IFNULL(BA.exitDate, NOW()) 

它那可能這是太多行,也許你需要一些其他的方式來處理(例如)只得到的日期,而不是完整的日期時間。但是,您應該經常通過caluse指定組中查詢的所有非聚合列。請參閱MySQL GROUP BY Extension