【问题标题】:Can I merge data from latest and oldest rows grouped by?我可以合并分组的最新和最旧行中的数据吗?
【发布时间】:2019-11-03 16:08:40
【问题描述】:

我想以某种方式合并这些 MySQL 5.6 结果。这个想法是从每个 id 的最新和最旧的行中获取数据。配对时间/id 值是唯一的。

表格是:

| time                | id | titulo   | precio | vendidos |
+---------------------+----+----------+--------+----------+
| 2019-10-26 19:12:14 | 1  | apple_a  | 2      | 10       |
| 2019-10-26 19:12:14 | 2  | pea      | 3      | 7        |
| 2019-10-26 19:12:14 | 3  | orange_a | 1      | 4        |
| 2019-10-28 19:12:14 | 3  | orange_a | 2      | 12       |
| 2019-10-28 19:12:14 | 4  | banana   | 5      | 7        |
| 2019-10-28 19:12:14 | 5  | peach    | 9      | 1        |
| 2019-10-29 19:12:14 | 1  | apple_b  | 2      | 12       |
| 2019-10-29 19:12:14 | 2  | pea      | 3      | 9        |
| 2019-10-29 19:12:14 | 3  | orange_b | 2      | 19       |
| 2019-10-29 19:12:14 | 4  | banana   | 6      | 14       |
| 2019-10-30 19:12:14 | 1  | apple_b  | 3      | 17       |
| 2019-10-30 19:12:14 | 2  | pea      | 3      | 11       |

带代码:

-- Get latest rows for each id:
SELECT b.*
FROM (SELECT t.id, MAX(time) AS latest
    FROM srapedpubs t GROUP BY id) a
INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.latest
ORDER BY id ASC
;

-- Get oldest rows for each id:
SELECT b.*
FROM (SELECT t.id, MIN(time) AS oldest
    FROM srapedpubs t GROUP BY id) a
INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.oldest
ORDER BY id ASC
;

结果是:

|                time | id |   titulo | precio | vendidos |
|---------------------|----|----------|--------|----------|
| 2019-10-30 19:12:14 |  1 |  apple_b |      3 |       17 |
| 2019-10-30 19:12:14 |  2 |      pea |      3 |       11 |
| 2019-10-29 19:12:14 |  3 | orange_b |      2 |       19 |
| 2019-10-29 19:12:14 |  4 |   banana |      6 |       14 |
| 2019-10-28 19:12:14 |  5 |    peach |      9 |        1 |

|                time | id |   titulo | precio | vendidos |
|---------------------|----|----------|--------|----------|
| 2019-10-26 19:12:14 |  1 |  apple_a |      2 |       10 |
| 2019-10-26 19:12:14 |  2 |      pea |      3 |        7 |
| 2019-10-26 19:12:14 |  3 | orange_a |      1 |        4 |
| 2019-10-28 19:12:14 |  4 |   banana |      5 |        7 |
| 2019-10-28 19:12:14 |  5 |    peach |      9 |        1 |

SQL 小提琴:

http://sqlfiddle.com/#!9/a9fafc/1

如何合并两个选择以从最旧和最新行中获取数据?最好省略相同的最旧和最新行(例如 id 5,“peach”)

期望的输出:

|                time | id |   titulo | precio | vendidos |         oldest_time | oldest_precio | oldest_vendidos |
|---------------------|----|----------|--------|----------|---------------------|---------------|-----------------|
| 2019-10-30 19:12:14 |  1 |  apple_b |      3 |       17 | 2019-10-26 19:12:14 |             2 |              10 |
| 2019-10-30 19:12:14 |  2 |      pea |      3 |       11 | 2019-10-26 19:12:14 |             3 |               7 |
| 2019-10-29 19:12:14 |  3 | orange_b |      2 |       19 | 2019-10-26 19:12:14 |             1 |               4 |
| 2019-10-29 19:12:14 |  4 |   banana |      6 |       14 | 2019-10-28 19:12:14 |             5 |               7 |

我不明白这是怎么做到的。我尝试了一些结果不正确的事情。那么这里有人知道怎么做吗?

【问题讨论】:

    标签: mysql time merge group-by greatest-n-per-group


    【解决方案1】:

    这对你来说是一个解决方案吗:

    select * from (
    SELECT b.*
    FROM (SELECT t.id, MAX(time) AS latest
        FROM srapedpubs t GROUP BY id) a
    INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.latest
    ORDER BY id ASC) one_t 
    left join 
    (SELECT b.*
    FROM (SELECT t.id, MIN(time) AS oldest
        FROM srapedpubs t GROUP BY id) a
    INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.oldest
    ORDER BY id ASC) two_t 
    on one_t.id = two_t.id
    where one_t.vendidos <> two_t.vendidos
    

    DEMO

    所以结果和你的问题一样:

    select one_t.time
          , one_t.id
          , one_t.titulo
          , one_t.precio
          , one_t.vendidos
          , two_t.time as oldest_time
          , two_t.precio as oldest_precio 
          , two_t.vendidos as oldest_vendidos  from (
    SELECT b.*
    FROM (SELECT t.id, MAX(time) AS latest
        FROM srapedpubs t GROUP BY id) a
    INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.latest
    ORDER BY id ASC) one_t 
    left join 
    (SELECT b.*
    FROM (SELECT t.id, MIN(time) AS oldest
        FROM srapedpubs t GROUP BY id) a
    INNER JOIN srapedpubs b ON b.id = a.id AND b.time = a.oldest
    ORDER BY id ASC) two_t 
    on one_t.id = two_t.id
    where one_t.vendidos <> two_t.vendidos
    

    DEMO

    【讨论】:

    • 太棒了!你真快!非常感谢!
    【解决方案2】:

    你快到了。现在,您有 2 个查询返回所需的信息。您只需要将它们连接在一起即可。

    SELECT a.latest as time,a.id,a.titulo,a.precio,a.vendidos,b.oldest as oldest_time, b.precio as oldest_precio, b.vendidos as oldest_vendidos
    FROM (
        SELECT id, MAX(time) AS latest, title, precious, vendidos
        FROM srapedpubs t 
        GROUP BY id
    ) a
    INNER JOIN (
        SELECT id, MAX(time) AS oldest, title, precious, vendidos
        FROM srapedpubs
        GROUP BY id
    ) b
    ON b.id=a.id
    WHERE b.oldest <> a.latest
    ORDER BY id ASC;
    

    【讨论】:

    • 感谢您的快速回复。通过联合,我可以在不同的行中获取数据。我需要它与问题中所需的输出相同。
    • 我已更新我的答案以使用 JOIN - UNION 不是正确的解决方案,我在看到同一行的记录要求之前发布了答案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多