3

我有下面的查询,它查看一个数据表,其中每一行都有一个 ID、日期/时间和关键操作(以及其他数据)。此表无法更改且不受我控制。

查询发现 Create 操作(始终是第一个)的出现,提取 ID 和 Date/Time for Creation,然后在一行中提取其他关键操作(Add Info、Book Appt、Accept)的 Date/Time数据:

SELECT _create.ID AS ID, 
_create.`datetime` AS Create, 
_inform.`datetime` AS Add_Info,
_bookap.`datetime` AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"

所以我得到类似的东西:

ID  -  Create Date - Inform Date - Bookap Date - Accept Date
1234   01/02/2013    02/02/2013    09/02/2013    10/02/2013 

这很好用。

但是,如果查询发现 2 个相同类型的事件,即同一 ID 的“Book Appt”,有时会发生这种情况,它会为该 ID 提取两行数据。所以我得到:

ID  -  Create Date - Inform Date - Bookap Date - Accept Date
1234   01/02/2013    02/02/2013    09/02/2013    10/02/2013 
1234   01/02/2013    02/02/2013    15/02/2013    10/02/2013     

我需要它忽略第二次出现,每个 ID 只返回一行。或者,更好地返回显示 Bookap Date1 和 Bookap Date2 的行。

有任何想法吗?

4

4 回答 4

3

用于GROUP BY将记录分组为一行,并min()选择最早的事件日期。

SELECT _create.ID AS ID, 
min(_create.`datetime`) AS Create, 
min(_inform.`datetime`) AS Add_Info,
min(_bookap.`datetime`) AS Book_Appt,
min(_accept.`datetime`) AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY _create.ID;

显示所有事件日期但仍返回一行的一种快速而肮脏的方法是使用该group_concat()函数而不是min()上面的查询。这会将多个datetimes 放入单个列中,然后您的应用层需要解析这些列。

于 2013-01-30T17:42:47.757 回答
0

如果要Book_Appt在一行中返回多个值,可以GROUP_CONCAT这样使用:

SELECT _create.ID AS ID, 
_create.`datetime` AS Create, 
_inform.`datetime` AS Add_Info,
GROUP_CONCAT(_bookap.`datetime`) AS Book_Appt,
_accept.`datetime` AS Accept,
FROM table AS _create
LEFT JOIN table AS _inform ON (_create.ID = _inform.ID AND _inform.action = 'Add Info')
LEFT JOIN table AS _bookap ON (_create.ID = _bookap.ID AND _bookap.action = 'Book Appt')
LEFT JOIN table AS _accept ON (_create.ID = _accept.ID AND _accept.action = 'Accept')
WHERE _create.action="Create"
GROUP BY `ID`

在您的情况下,这将返回一个逗号分隔的日期时间值列表。

所以你的输出可能看起来像

ID  -  Create Date - Inform Date - Bookap Date      -       Accept Date
1234   01/02/2013    02/02/2013    09/02/2013,15/02/2013    10/02/2013 
于 2013-01-30T17:44:28.610 回答
0

当然,GROUP BY _create.ID在你的WHERE条款之后使用。

于 2013-01-30T17:41:38.723 回答
0

对于您的第一个问题(仅返回一行),我将使用一个ORDER BY子句对您的结果集进行排序,然后是一个LIMIT 1仅返回一行的表达式。

于 2013-01-30T17:59:53.107 回答