MySQL select 最后 N 组的所有行

MySQL select all rows from last N groups

我有一个这样的数据集,其中每笔交易可以有多个交易

| tx_id | trade_id |
--------------------
| 100   | 11       |
| 99    | 11       |
| 98    | 11       |
| 97    | 10       |
| 96    | 10       |
| 95    | 9        |
| 94    | 9        |
| 93    | 8        |
...

我想select最近N笔交易的所有交易。例如,如果我想 select 最后 2 笔交易的所有行,我会得到:

| tx_id | trade_id |
--------------------
| 100   | 11       |
| 99    | 11       |
| 98    | 11       |
| 97    | 10       |
| 96    | 10       |

我不能保证 trade_id 的间隔始终为 1。

如何在 mysql 中完成此操作?

您在 trade_id 上使用 DENSE_RANK 降序,然后根据您需要的 X 过滤“最后一个 X”:

CREATE TABLE t (tx_id int, trade_id int);

INSERT INTO t (tx_id, trade_id) VALUES
(100,11),
(99,11),
(98,11),
(97,10),
(96,10),
(95,9),
(94,9),
(93,8);

SET @ngroups=2;

WITH dat
AS
(
SELECT tx_id, trade_id, DENSE_RANK() OVER (ORDER BY trade_id DESC) AS trade_id_rank
FROM t
)
SELECT tx_id, trade_id
FROM dat
WHERE trade_id_rank <= @ngroups;

dbfiddle.uk

如果我们假设“最后交易”是具有最高 trade_id 数字的交易,那么您可以使用 DENSE_RANK().

例如:

select *
from (
  select *,
    dense_rank() over(order by trade_id desc) as dr
  from t
) x
where dr <= 2

这可以通过 CTE 来完成

WITH trades AS
SELECT trade_id tid
FROM myTable
GROUP BY trade_id
ORDER BY trade_id
LIMIT 2
SELECT * FROM
trades 
JOIN myTable ON trade_id = tid
ORDER BY tx_id;

这也适用于 mysql 5

更改限制,您可以选择要接收的交易数量

CREATE TABLE tab1 (
  `tx_id` INTEGER,
  `trade_id` INTEGER
);

INSERT INTO tab1
  (`tx_id`, `trade_id`)
VALUES
  ('100', '11'),
  ('99', '11'),
  ('98', '11'),
  ('97', '10'),
  ('96', '10'),
  ('95', '9'),
  ('94', '9'),
  ('93', '8');
SELECT t1.* FROM tab1 t1 JOIN (SELECT DISTINCT `trade_id` FROM tab1 ORDER BY `trade_id`  DESC LIMIT 2) t2
ON t1.`trade_id` = t2.`trade_id`
tx_id | trade_id
----: | -------:
  100 |       11
   99 |       11
   98 |       11
   97 |       10
   96 |       10

db<>fiddle here