SQL SELECT 仅当记录数大于 N 时显示记录
SQL SELECT showing records only if the number of records is greater than N
我有一个这样定义的 table (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
);
示例数据集:
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);
我需要显示符合特定条件的记录(假设 lastname = 'Santucci'
)仅当记录数大于特定定义的限制(假设为 2)时。
我以各种方式尝试但没有成功,最有希望的形式是:
SELECT
id,
firstname,
lastname
FROM
mysql_test_a
WHERE
lastname = 'Santucci'
HAVING COUNT(*) > 2
它returns只有第一条记录。
我更喜欢使用这种形式,因为 HAVING 子句将允许使用参数。
--- 最新更新---
我必须更具体地说明解决方案:我正在寻找不涉及内部 SELECT
的内容,更具体地说是它的 WHERE
子句,因为正如我指出的那样,所提供的是非常假设的(即它可能与此完全不同并且复杂得多)。当然,我很感激任何其他提示。
您可以在查询中使用子查询,如下所示:
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
您可能正在寻找这个:
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
我猜你的结果是
1 Marcello Santucci
但你想要这样的东西:
1 Marcello Santucci
2 Mike Santucci
4 Matilde Josefa Santucci
5 Milena Santucci
在这种情况下,您可以使用此查询,类似于@Popeye 的建议:
SELECT id, firstname, lastname
FROM mysql_test_a tbl
WHERE (SELECT count(*) FROM mysql_test_a sbq WHERE sbq.lastname = tbl.lastname) > 2
或者这个,基于'in'运算符
的用法
SELECT * from mysql_test_a
WHERE lastname IN (
SELECT lastname
FROM mysql_test_a
GROUP BY lastname
HAVING COUNT(lastname) >2
)
您可以添加 'WHERE' 子句以将结果限制为 'Santucci',但我认为您会感兴趣更通用的答案。
我也准备了一个小fiddle可以玩http://sqlfiddle.com/#!9/b1a727/16
如果你是 运行 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
我们可以将其概括为一次处理多个姓氏:
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
最有效的方法可能是 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
);
为了性能,您需要 mysql_test_a(lastname)
上的索引。
我有一个这样定义的 table (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
);
示例数据集:
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);
我需要显示符合特定条件的记录(假设 lastname = 'Santucci'
)仅当记录数大于特定定义的限制(假设为 2)时。
我以各种方式尝试但没有成功,最有希望的形式是:
SELECT
id,
firstname,
lastname
FROM
mysql_test_a
WHERE
lastname = 'Santucci'
HAVING COUNT(*) > 2
它returns只有第一条记录。
我更喜欢使用这种形式,因为 HAVING 子句将允许使用参数。
--- 最新更新---
我必须更具体地说明解决方案:我正在寻找不涉及内部 SELECT
的内容,更具体地说是它的 WHERE
子句,因为正如我指出的那样,所提供的是非常假设的(即它可能与此完全不同并且复杂得多)。当然,我很感激任何其他提示。
您可以在查询中使用子查询,如下所示:
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
您可能正在寻找这个:
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
我猜你的结果是
1 Marcello Santucci
但你想要这样的东西:
1 Marcello Santucci
2 Mike Santucci
4 Matilde Josefa Santucci
5 Milena Santucci
在这种情况下,您可以使用此查询,类似于@Popeye 的建议:
SELECT id, firstname, lastname
FROM mysql_test_a tbl
WHERE (SELECT count(*) FROM mysql_test_a sbq WHERE sbq.lastname = tbl.lastname) > 2
或者这个,基于'in'运算符
的用法SELECT * from mysql_test_a
WHERE lastname IN (
SELECT lastname
FROM mysql_test_a
GROUP BY lastname
HAVING COUNT(lastname) >2
)
您可以添加 'WHERE' 子句以将结果限制为 'Santucci',但我认为您会感兴趣更通用的答案。
我也准备了一个小fiddle可以玩http://sqlfiddle.com/#!9/b1a727/16
如果你是 运行 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
我们可以将其概括为一次处理多个姓氏:
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
最有效的方法可能是 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
);
为了性能,您需要 mysql_test_a(lastname)
上的索引。