MySQL 查询,MAX() +分组依据

发布于 2024-11-01 13:50:16 字数 1358 浏览 2 评论 0原文

愚蠢的 SQL 问题。我有一个像这样的表(“pid”是自动递增主列)

CREATE TABLE theTable (
    `pid` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    `timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `cost` INT UNSIGNED NOT NULL,
    `rid` INT NOT NULL,
) Engine=InnoDB;

实际表数据:

INSERT INTO theTable (`pid`, `timestamp`, `cost`, `rid`)
VALUES
  (1, '2011-04-14 01:05:07', 1122, 1),
  (2, '2011-04-14 00:05:07', 2233, 1),
  (3, '2011-04-14 01:05:41', 4455, 2),
  (4, '2011-04-14 01:01:11', 5566, 2),
  (5, '2011-04-14 01:06:06', 345, 1),
  (6, '2011-04-13 22:06:06', 543, 2),
  (7, '2011-04-14 01:14:14', 5435, 3),
  (8, '2011-04-14 01:10:13', 6767, 3)
;

我想获取每个rid的最新行的PID(每个唯一的RID有1个结果)。对于示例数据,我想:

pid | MAX(timestamp)      | rid
-----------------------------------
5   | 2011-04-14 01:06:06 | 1
3   | 2011-04-14 01:05:41 | 2
7   | 2011-04-14 01:14:14 | 3

我尝试运行以下查询:

SELECT MAX(timestamp),rid,pid FROM theTable GROUP BY rid

并且我得到:

max(timestamp)     ; rid; pid
----------------------------
2011-04-14 01:06:06; 1  ; 1
2011-04-14 01:05:41; 2  ; 3
2011-04-14 01:14:14; 3  ; 7

返回的 PID 始终是 RID 的 PID 的第一次出现(行/pid 1 是第一次使用 rod 1,行/pid 3 是第一次使用 RID 2,row /pid 7 是第一次使用 rod 3)。虽然返回每个 Rid 的最大时间戳,但 pid 不是原始表中时间戳的 pid。什么查询会给我我正在寻找的结果?

Daft SQL question. I have a table like so ('pid' is auto-increment primary col)

CREATE TABLE theTable (
    `pid` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
    `timestamp` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `cost` INT UNSIGNED NOT NULL,
    `rid` INT NOT NULL,
) Engine=InnoDB;

Actual table data:

INSERT INTO theTable (`pid`, `timestamp`, `cost`, `rid`)
VALUES
  (1, '2011-04-14 01:05:07', 1122, 1),
  (2, '2011-04-14 00:05:07', 2233, 1),
  (3, '2011-04-14 01:05:41', 4455, 2),
  (4, '2011-04-14 01:01:11', 5566, 2),
  (5, '2011-04-14 01:06:06', 345, 1),
  (6, '2011-04-13 22:06:06', 543, 2),
  (7, '2011-04-14 01:14:14', 5435, 3),
  (8, '2011-04-14 01:10:13', 6767, 3)
;

I want to get the PID of the latest row for each rid (1 result per unique RID). For the sample data, I'd like:

pid | MAX(timestamp)      | rid
-----------------------------------
5   | 2011-04-14 01:06:06 | 1
3   | 2011-04-14 01:05:41 | 2
7   | 2011-04-14 01:14:14 | 3

I've tried running the following query:

SELECT MAX(timestamp),rid,pid FROM theTable GROUP BY rid

and I get:

max(timestamp)     ; rid; pid
----------------------------
2011-04-14 01:06:06; 1  ; 1
2011-04-14 01:05:41; 2  ; 3
2011-04-14 01:14:14; 3  ; 7

The PID returned is always the first occurence of PID for an RID (row / pid 1 is frst time rid 1 is used, row / pid 3 the first time RID 2 is used, row / pid 7 is first time rid 3 is used). Though returning the max timestamp for each rid, the pids are not the pids for the timestamps from the original table. What query would give me the results I'm looking for?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

乖乖兔^ω^ 2024-11-08 13:50:17

如果你想避免 JOIN,你可以使用:

SELECT pid, rid FROM theTable t1 WHERE t1.pid IN ( SELECT MAX(t2.pid) FROM theTable t2 GROUP BY t2.rid);

If you want to avoid a JOIN, you can use:

SELECT pid, rid FROM theTable t1 WHERE t1.pid IN ( SELECT MAX(t2.pid) FROM theTable t2 GROUP BY t2.rid);
对不⑦ 2024-11-08 13:50:17

尝试:

select pid,cost, timestamp, rid from theTable order by timestamp DESC limit 2;

Try:

select pid,cost, timestamp, rid from theTable order by timestamp DESC limit 2;
泪眸﹌ 2024-11-08 13:50:16

(在 PostgreSQL 9.something 中测试)

识别 Rid 和时间戳。

select rid, max(timestamp) as ts
from test
group by rid;

1   2011-04-14 18:46:00
2   2011-04-14 14:59:00

加入它。

select test.pid, test.cost, test.timestamp, test.rid
from test
inner join 
    (select rid, max(timestamp) as ts
    from test
    group by rid) maxt
on (test.rid = maxt.rid and test.timestamp = maxt.ts)

(Tested in PostgreSQL 9.something)

Identify the rid and timestamp.

select rid, max(timestamp) as ts
from test
group by rid;

1   2011-04-14 18:46:00
2   2011-04-14 14:59:00

Join to it.

select test.pid, test.cost, test.timestamp, test.rid
from test
inner join 
    (select rid, max(timestamp) as ts
    from test
    group by rid) maxt
on (test.rid = maxt.rid and test.timestamp = maxt.ts)
雨轻弹 2024-11-08 13:50:16
select *
from (
    select `pid`, `timestamp`, `cost`, `rid`
    from theTable 
    order by `timestamp` desc
) as mynewtable
group by mynewtable.`rid`
order by mynewtable.`timestamp`

希望我有帮助!

select *
from (
    select `pid`, `timestamp`, `cost`, `rid`
    from theTable 
    order by `timestamp` desc
) as mynewtable
group by mynewtable.`rid`
order by mynewtable.`timestamp`

Hope I helped !

原谅我要高飞 2024-11-08 13:50:16
SELECT t.pid, t.cost, to.timestamp, t.rid
FROM test as t
JOIN (
    SELECT rid, max(tempstamp) AS maxtimestamp
    FROM test GROUP BY rid
) AS tmax
    ON t.pid = tmax.pid and t.timestamp = tmax.maxtimestamp
SELECT t.pid, t.cost, to.timestamp, t.rid
FROM test as t
JOIN (
    SELECT rid, max(tempstamp) AS maxtimestamp
    FROM test GROUP BY rid
) AS tmax
    ON t.pid = tmax.pid and t.timestamp = tmax.maxtimestamp
笑饮青盏花 2024-11-08 13:50:16

我在rid和时间戳上创建了一个索引。

SELECT test.pid, test.cost, test.timestamp, test.rid
FROM theTable AS test
LEFT JOIN theTable maxt 
ON maxt.rid = test.rid
AND maxt.timestamp > test.timestamp
WHERE maxt.rid IS NULL 

显示第 0 - 2 行(总共 3 行,查询花费了 0.0104 秒)

此方法将从 theTable (测试)中选择所有所需的值,在所有高于测试时间戳的时间戳上左连接自身 (maxt)与同样的摆脱。当时间戳已经是测试中最高的时间戳时,maxt 上没有匹配项 - 这就是我们正在寻找的 - maxt 上的值变为 NULL。现在我们使用 WHERE 子句 maxt.rid IS NULL 或 maxt 上的任何其他列。

I created an index on rid and timestamp.

SELECT test.pid, test.cost, test.timestamp, test.rid
FROM theTable AS test
LEFT JOIN theTable maxt 
ON maxt.rid = test.rid
AND maxt.timestamp > test.timestamp
WHERE maxt.rid IS NULL 

Showing rows 0 - 2 (3 total, Query took 0.0104 sec)

This method will select all the desired values from theTable (test), left joining itself (maxt) on all timestamps higher than the one on test with the same rid. When the timestamp is already the highest one on test there are no matches on maxt - which is what we are looking for - values on maxt become NULL. Now we use the WHERE clause maxt.rid IS NULL or any other column on maxt.

等数载,海棠开 2024-11-08 13:50:16

您也可以有这样的子查询:

SELECT ( SELECT MIN(t2.pid)
         FROM test t2
         WHERE t2.rid = t.rid
           AND t2.timestamp = maxtimestamp
       ) AS pid 
     , MAX(t.timestamp) AS maxtimestamp
     , t.rid
FROM test t
GROUP BY t.rid

但是这样,如果您希望将 cost 包含在显示的列中,等等,您将需要一个子查询。

因此,group byjoin 是更好的解决方案。

You could also have subqueries like that:

SELECT ( SELECT MIN(t2.pid)
         FROM test t2
         WHERE t2.rid = t.rid
           AND t2.timestamp = maxtimestamp
       ) AS pid 
     , MAX(t.timestamp) AS maxtimestamp
     , t.rid
FROM test t
GROUP BY t.rid

But this way, you'll need one more subquery if you want cost included in the shown columns, etc.

So, the group by and join is better solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文