简体   繁体   English

SQL SELECT 仅当记录数大于N时显示记录

[英]SQL SELECT showing records only if the number of records is greater than N

I have a table defined like this (MySQL 5.1):我有一个这样定义的表(MySQL 5.1):

CREATE TABLE mysql_test_a ( 
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY, 
firstname VARCHAR(30) NOT NULL, 
lastname VARCHAR(30) NOT NULL,  
email VARCHAR(50), 
reg_date TIMESTAMP 
); 

Sample dataset:示例数据集:

INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('1', 'Marcello', 'Santucci', 'marcello@tux.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('2', 'Mike', 'Santucci', 'mike@tux.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('3', 'Anna Maria', 'Gabriele', 'anna.maria@gabriele.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('4', 'Matilde Josefa', 'Santucci', 'matilde.josefa@tux.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('5', 'Milena', 'Santucci', 'mile@tux.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('6', 'Luca', 'Pensa', 'luca@pensa.net', CURRENT_TIMESTAMP); 
INSERT INTO `mysql_test_a` (`id`, `firstname`, `lastname`, `email`, `reg_date`) VALUES ('7', 'Lorenzo', 'Pensa', 'lo@pensa.net', CURRENT_TIMESTAMP); 

I need to show records matching a certain criteria (lets suppose lastname = 'Santucci' ) only if the number of records is greater than a certain defined limit (lets say 2).仅当记录数大于某个定义的限制(假设为 2)时,我才需要显示符合特定条件的记录(假设lastname = 'Santucci' )。 I tried in various way without success the most promising form was:我以各种方式尝试但没有成功,最有希望的形式是:

SELECT
    id,
    firstname,
    lastname
FROM
    mysql_test_a
WHERE
    lastname = 'Santucci'
HAVING COUNT(*) > 2

It returns only the first record.它只返回第一条记录。

I would prefer to use something like this form because HAVING clause will enable the use of a parameter.我更愿意使用类似这种形式的东西,因为 HAVING 子句将允许使用参数。

--- LATE UPDATE --- --- 最新更新 ---

I have to be more specific on the solution: I'm looking for something that do not deal with the inner SELECT and more specifically its WHERE clause because, as I pointed out, the one provided is pretty hypotetical (ie it can be quite different from this and much more complex).我必须更具体地说明解决方案:我正在寻找不处理内部SELECT的东西,更具体地说是它的WHERE子句,因为正如我指出的那样,提供的那个是非常虚构的(即它可能完全不同从此复杂得多)。 Of course I appreciate any other hint.当然,我很欣赏任何其他提示。

You can use the sub-query in your query as follows:您可以在查询中使用子查询,如下所示:

SELECT id, firstname, lastname
FROM mysql_test_a a
WHERE lastname = 'Santucci'
  and (select count(1) from mysql_test_a b where b.lastname  = a.lastname) > 2

You may be looking for this:您可能正在寻找这个:

SELECT 
 *
 FROM
    (SELECT 
        id, 
        firstname, 
        lastname
    FROM
        mysql_test_a
    WHERE
        lastname = 'Santucci') a,
    (SELECT 
        id, 
        firstname, 
        lastname
    FROM
        mysql_test_a
    WHERE
        lastname = 'Santucci'
    HAVING COUNT(*) > 2) b
WHERE
    a.lastname = b.lastname

I am guessing that your result is我猜你的结果是

1 Marcello Santucci

but you want something like this:但你想要这样的东西:

1   Marcello        Santucci
2   Mike            Santucci
4   Matilde Josefa  Santucci
5   Milena          Santucci

In this case, you can use this query, similar to what @Popeye suggested:在这种情况下,您可以使用此查询,类似于@Popeye 的建议:

SELECT id, firstname, lastname
FROM mysql_test_a tbl
WHERE (SELECT count(*) FROM mysql_test_a sbq WHERE sbq.lastname  = tbl.lastname) > 2

or this one, based on the usage of the 'in' operator或这个,基于“in”运算符的用法

SELECT * from mysql_test_a
WHERE lastname IN (
    SELECT lastname
    FROM mysql_test_a
    GROUP BY lastname
    HAVING COUNT(lastname) >2
)

You can add 'WHERE' clauses to limit the result to 'Santucci', but I assume that a more generic answer is of interest to you.您可以添加“WHERE”子句以将结果限制为“Santucci”,但我认为您对更通用的答案感兴趣。

I have also prepared a small fiddle that you can play with http://sqlfiddle.com/#!9/b1a727/16我还准备了一个小提琴,你可以玩http://sqlfiddle.com/#!9/b1a727/16

If you are running MySQL 8.0, I would recommend a window count:如果您运行的是 MySQL 8.0,我建议使用 window 计数:

select id, firstname, lastname
from (
    select t.*, count(*) over() as cnt
    from mysql_test_a a
    where lastname = 'Santucci'
) t
where cnt > 2

We can generalize this to handle multiple last names at once:我们可以将其概括为一次处理多个姓氏:

select id, firstname, lastname
from (
    select t.*, count(*) over(partition by lastname) as cnt
    from mysql_test_a a
) t
where cnt > 2
order by lastname

The most efficient method might be exists :最有效的方法可能exists

select t.*
from mysql_test_a t
where lastname = 'Santucci' and
      exists (select 1
              from mysql_test_a t2 
              where t2.lastname = t.lastname and
                    t2.id <> t.id
             );

For performance, you want an index on mysql_test_a(lastname) .为了提高性能,您需要在mysql_test_a(lastname)上建立索引。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM