如何从组中的mysql数据库中检索记录数?

时间:2018-04-18 11:14:28

标签: mysql sql

我有一张包含多条记录的表格,用于全名和姓氏。

---------------------------
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

有人可以建议我更好地检索我的目标。

1 个答案:

答案 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;它肯定将结构化放在结构化查询语言中。