gpt4 book ai didi

mysql - SQL - 每个名字一行

转载 作者:可可西里 更新时间:2023-11-01 08:58:38 29 4
gpt4 key购买 nike

尝试利用 https://stackoverflow.com/a/123481 中的技术我正在尝试为每个 name 检索一行,具有特定的排序,即按 activecreated< 降序排序后的第一行/第一行,然后是 prid。但是,active 列可能包含数字或 NULL 值,这会导致 name=bat 情况下出现重复。任何帮助将不胜感激。

源表:

+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 1 | bat | NULL | 3 |
| 2 | bat | 1 | 2 |
| 3 | bat | 2 | 1 |
| 4 | bat | 3 | 0 |
| 5 | noise | NULL | 2 |
| 6 | noise | NULL | 1 |
| 7 | cup | NULL | 0 |
| 8 | cup | NULL | 0 |
| 9 | egg | 4 | 4 |
| 10 | egg | 4 | 2 |
+------+-------+--------+---------+

期望的结果:

+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 9 | egg | 4 | 4 |
| 4 | bat | 3 | 0 |
| 5 | noise | NULL | 2 |
| 8 | cup | NULL | 0 |
+------+-------+--------+---------+

SQL:

SELECT p1.*
FROM source_table p1
LEFT JOIN source_table p2 ON (
p1.name = p2.name
AND (
p1.active < p2.active
OR (
(p1.active = p2.active OR (p1.active IS NULL AND p2.active IS NULL))
AND (
p1.created < p2.created
OR (
p1.created = p2.created AND p1.prid < p2.prid
)
)
)
)
)
WHERE p2.prid IS NULL
ORDER BY p1.active DESC, p1.created DESC, p1.prid DESC

实际结果:

+------+-------+--------+---------+
| prid | name | active | created |
+------+-------+--------+---------+
| 9 | egg | 4 | 4 |
| 4 | bat | 3 | 0 |
| 1 | bat | NULL | 3 |
| 5 | noise | NULL | 2 |
| 8 | cup | NULL | 0 |
+------+-------+--------+---------+

@Gordon Linoff

感谢您的帮助,我尝试使用带有索引 (name, active, created, prid)(active, created, prid) 的第二个版本,但是速度很慢。

这需要 1 秒,返回正确的结果,但顺序错误:

SELECT t1.prid
FROM source_table t1
WHERE t1.prid = (
SELECT t2.prid
FROM source_table t2
WHERE t2.name = t1.name
ORDER BY t2.active DESC, t2.created DESC, t2.prid DESC
LIMIT 1
)
LIMIT 50

这需要 55 秒:

SELECT t1.prid
FROM source_table t1
WHERE t1.prid = (
SELECT t2.prid
FROM source_table t2
WHERE t2.name = t1.name
ORDER BY t2.active DESC, t2.created DESC, t2.prid DESC
LIMIT 1
)
ORDER BY t1.active DESC, t1.created DESC, t1.prid DESC
LIMIT 50

我真的需要 LIMIT 500,有什么想法吗?


@Rick James

SQL Fiddle 链接:http://sqlfiddle.com/#!9/f9b39/2/0

最佳答案

使用 ANSI 标准的 row_number() 函数:

select t.*
from (select t.*,
row_number() over (partition by name
order by active desc, created desc, pid desc
) as seqnum
from source_table t
) t
where seqnum = 1;

以上适用于 MySQL 8+ 和 MariaDB 10.2+。在早期版本中,您可以:

select t.*
from source_table t
where t.prid = (select t2.prid
from source_table t2
where t2.name = t.name
order by t2.active desc, t2.created desc, t2.pid desc
limit 1
);

为了提高性能,您需要在 source_table(name, actdive desc, created desc, pid desc, prid) 上建立索引。

关于mysql - SQL - 每个名字一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51304173/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com