我有一张包含多条记录的表格,用于全名和姓氏。
---------------------------
id | name | lastname
---------------------------
1 | A smith | smith
2 | B smith | smith
3 | c smith | smith
4 | A josh | josh
5 | B josh | josh
6 | C josh | josh
7 | D josh | josh
8 | A white | white
9 | D white | white
10| z white | white
等等......超过10万条记录。现在我想做的是为每个姓氏检索最多7个姓氏的最新7条记录。我有500个姓氏,但我只想要最新的9个姓氏..在我的申请中,“最新”表示“id
列的最大值。”
这是我试图制作的命令,但是当我执行它时。我没有收到服务器的任何回复。由于数据库大小而发生这种情况,我的命令花费了大量时间。它只是让我等着:
SELECT * FROM `queue` s WHERE ( SELECT COUNT(*) FROM `queue` f WHERE f.lastname = s.lastname AND f.id >= s.id LIMIT 0 , 7) <=7
有人可以建议我更好地检索我的目标。
答案 0 :(得分:1)
让我们从基础知识构建它。
您的第一步是创建子查询以获取最新的九个姓氏(http://sqlfiddle.com/#!9/aee62e/19/0)。我的意思是具有最高id
值的姓氏。
SELECT lastname, MAX(id) namerank
FROM t
GROUP BY lastname
ORDER BY MAX(id) DESC
LIMIT 9
而且,在MySQL中,这很容易。现在,您需要为每个选定的姓氏检索七个排名最高(最大id
)行。首先,您可以执行此操作以按ID降序获取所选姓氏的所有记录。 (http://sqlfiddle.com/#!9/aee62e/18/0)。
SELECT t.*, namerank
FROM t
JOIN (
SELECT lastname, MAX(id) namerank
FROM t
GROUP BY lastname
ORDER BY MAX(id) DESC
LIMIT 9
) h ON t.lastname = h.lastname
ORDER BY t.lastname, t.id DESC
这是正确的,但包含太多行。接下来,我们需要获取每个lastname
行的排名。排名越低意味着id
值越高。这是MySQL中令人讨厌的黑客攻击。 (令人讨厌,因为它将局部变量的过程操作与SQL的固有声明性混合在一起。)(http://sqlfiddle.com/#!9/aee62e/17/0)
SELECT IF(detail.lastname = @prev_lastname, @rank := @rank+1, @rank :=1) rank,
namerank,
@prev_lastname := detail.lastname lastname,
id,
name
FROM (
SELECT t.*, namerank
FROM t
JOIN (
SELECT lastname, MAX(id) namerank
FROM t
GROUP BY lastname
ORDER BY MAX(id) DESC
LIMIT 9
) h ON t.lastname = h.lastname
ORDER BY t.lastname, t.id DESC
) detail
JOIN (SELECT @rank := 0, @prev_lastname := '') initializer
最后,我们需要在外部查询中包含整个混乱,以便为每个lastname
值选择排名最高的七行。 (http://sqlfiddle.com/#!9/aee62e/16/0)
SELECT *
FROM (
SELECT IF(detail.lastname = @prev_lastname, @rank := @rank+1, @rank :=1) rank,
namerank,
@prev_lastname := detail.lastname lastname,
id,
name
FROM (
SELECT t.*, namerank
FROM t
JOIN (
SELECT lastname, MAX(id) namerank
FROM t
GROUP BY lastname
ORDER BY MAX(id) DESC
LIMIT 9
) h ON t.lastname = h.lastname
ORDER BY t.lastname, t.id DESC
) detail
JOIN (SELECT @rank := 0, @prev_lastname := '') initializer
) ranked
WHERE rank <= 7
ORDER BY namerank DESC, rank
我相信您的要求和此解决方案的复杂性的技术术语是&#34;毛球。&#34;它肯定将结构化放在结构化查询语言中。