2列上的间隙和岛-如果A列连续且B列相同
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2列上的间隙和岛-如果A列连续且B列相同相关的知识,希望对你有一定的参考价值。
我的表格如下:
CREATE TABLE `table` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cc` int(3) unsigned NOT NULL,
`number` int(10) NOT NULL,
`name` varchar(64) NOT NULL,
`datetime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB
DBMS是Debian 9.1上的MariaDB 10.1.26。我一直试图让它列出连续数字的范围。通过以下查询,我能够实现这一点:
SELECT min(number) first_number, max(number) last_number, count(*) AS no_records FROM (
SELECT c.*, @rn := @rn + 1 rn
from (SELECT number FROM table WHERE cc = 1 GROUP BY number ORDER BY number) AS c
CROSS JOIN (SELECT @rn := 0) r
) c
GROUP BY number - rn ORDER BY number ASC
但是,如果我希望根据其他列中的值将项目捆绑在一起,则无法使用。说我只在name
的值都相同时才将项目分组。说这是我的数据:
INSERT INTO `table` (`id`, `cc`, `number`, `name`) VALUES
(1, 1, 12, 'Hello'),
(2, 1, 2, 'Apple'),
(3, 1, 3, 'Bean'),
(4, 1, 10, 'Hello'),
(5, 1, 11, 'Hello'),
(6, 1, 1, 'Apple'),
(7, 1, 14, 'Deer'),
(8, 1, 14, 'Door'),
我想得到这样的报告:
first last count name
1 2 2 Apple
3 3 1 Bean
10 12 3 Hello
14 14 1 Deer
14 14 1 Door
换句话说,除了将连续的项目分组外,当它们的name
的值不同时,这些组也被分为单独的组。 (换句话说,如果项目都是连续的并且具有相同的精确name
,则它们仅在一个岛中在一起)。我最近的(不是很接近)正在执行此操作:
SELECT min(number) first_number, max(number) last_number, count(*) AS no_records FROM (
SELECT c.*, @rn := @rn + 1 rn
from (SELECT number FROM table WHERE cc = 1 GROUP BY number, name ORDER BY number) AS c
CROSS JOIN (SELECT @rn := 0) r
) c
GROUP BY number - rn, name ORDER BY number ASC
但是,这不起作用,发生的事情似乎是将名称的第一个出现返回为first
,最后一个出现返回为last
,其中no_records
是它们之间的数字差,当然是不对的。
我感觉很像this question might be related,但是我并没有太大的意义,当我尝试将其调整到表中时,它或多或少地相当于一个简单的SELECT *
。我需要对查询进行哪些修改才能使其正常工作?
答案
您的例子不是一个孤岛问题。如果它代表您的实际问题,则可以使用聚合:
select min(number), max(number), count(*), name
from t
group by name;
我之所以这样说,是因为如果没有窗口功能,差距和岛屿将更具挑战性。这就引出了一个问题,即为什么不使用更新版本的MariaDB。无论如何,10.1的寿命终止于今年10月。
以上是关于2列上的间隙和岛-如果A列连续且B列相同的主要内容,如果未能解决你的问题,请参考以下文章