“分组依据”列,返回最近的AND最早的字段

时间:2017-01-11 18:12:59

标签: mysql group-by timestamp

我有一张桌子:

ITEM    NOTE        RECORD_DATE             USER
Apple   Blah        2016-12-30 11:22:33     mcmurphy510
Orange  Somenote    2016-12-31 11:22:33     user2
Apple   BlahBlah    2017-01-01 11:22:33     user2

我试图创建一个显示Item的查询,以及最近的Note。我还需要从DATE和USER列中删除四个字段:

CREATED:应该是给定RECORD_DATE最早行的ITEM时间戳

CREATED_BY:应该是给定USER最早行的ITEM

UPDATED:应该是给定RECORD_DATE最新行的ITEM时间戳

UPDATED_BY:应该是给定USER最新行的ITEM

我使用以下查询设法获得了一个或另一个(最早或最晚),但不是两者都是:

SELECT
    i.item,
    i.note,
    i.record_date AS created,
    i.user AS created_by
FROM
    item i
    INNER JOIN (
        SELECT
            item,
            MAX(record_date) as record_date
        FROM item
        GROUP BY item
    ) i2
        ON (
            i.item = i2.item AND
            i.record_date = i2.record_date
        )

使用此功能,我可以通过在子查询中切换RECORD_DATEMAX()来切换最早的和最近的MIN()

我的问题是如何创建一个可以在同一行显示最早和最近结果的单一查询?

期望的结果:

ITEM    NOTE        CREATED                 CREATED_BY      UPDATED                 UPDATED_BY
Apple   BlahBlah    2016-12-30 11:22:33     mcmurphy510     2017-01-01 11:22:33     user2
Orange  Somenote    2016-12-31 11:22:33     user2           NULL                    NULL

我这里有一个小提琴: http://sqlfiddle.com/#!9/cd724a/3

2 个答案:

答案 0 :(得分:1)

您可以找到每个项目的最早和最晚日期,然后像这样加入主表:

select
    i1.item,
    i2.note,
    i1.record_date created_date,
    i1.user create_user,
    case when i1.record_date <> i2.record_date then i2.record_date end update_date,
    case when i1.record_date <> i2.record_date then i2.user end update_user
from item i1
inner join item i2
on i1.item = i2.item
inner join (
select item, min(record_date) mn, max(record_date) mx
from item
group by item
) i3 on i1.item = i3.item
and i1.record_date = i3.mn
and i2.record_date = i3.mx;

SQLFiddle

答案 1 :(得分:0)

您可以一次计算第一个和最后一个,并在连接条件中使用它们,如下所示:

http://your.site/test/123/1234

或者,您可以通过在子查询上使用UNION来获得更快的查询,并避免上述SELECT i.item, i.note, i.record_date AS created, i.user AS created_by FROM item i INNER JOIN ( SELECT item , MAX(record_date) as lastDate , MIN(record_date) as firstDate FROM item GROUP BY item ) AS flDates ON i.item = flDates.item AND i.record_date IN (flDates.firstDate, flDates.lastDate) 条件隐含的索引浪费OR,如下所示:

IN

如果表的索引位于SELECT i.item, i.note, i.record_date AS created, i.user AS created_by FROM item i INNER JOIN ( SELECT item, MIN(record_date) as record_date FROM item GROUP BY item UNION SELECT item, MAX(record_date) as record_date FROM item GROUP BY item ) AS flDates ON i.item = flDates.item AND i.record_date = flDates.record_date ,则更有可能比第一个版本更快;但如果没有这样的索引,(item, record_date)MIN值的单独计算可能会花费更长的时间。