统一MySQL中不同行的相邻范围
假设有一家公司有几个部门。他们每个人都有一个或几个范围的内部电话号码分配给它。分配存储在一个数据库表中,但对于不同的部门,存储方式不同,如下所示:统一MySQL中不同行的相邻范围,mysql,sql,select,Mysql,Sql,Select,假设有一家公司有几个部门。他们每个人都有一个或几个范围的内部电话号码分配给它。分配存储在一个数据库表中,但对于不同的部门,存储方式不同,如下所示: dept_name range_start range_end Sales 10 19 Sales 20 29 HR 30 49 Finance 60 65 Finance
dept_name range_start range_end
Sales 10 19
Sales 20 29
HR 30 49
Finance 60 65
Finance 84 93
dept_name range_start range_end
Sales 10 29
HR 30 49
Finance 60 65
Finance 84 93
如何将相邻范围选择为联合,以便销售部门的结果中只有一行,如下所示:
dept_name range_start range_end
Sales 10 19
Sales 20 29
HR 30 49
Finance 60 65
Finance 84 93
dept_name range_start range_end
Sales 10 29
HR 30 49
Finance 60 65
Finance 84 93
可以通过查找所有范围的开始、结束,然后按正确的顺序将它们连接在一起来完成 这里有一个SQLFIDLE演示了这个概念: 而查询
SELECT oStart.dept_name, oStart.range_start, oEnd.range_end
FROM
(
SELECT strt.dept_name, strt.range_start, @rownum := @rownum + 1 AS rank
FROM
(
SELECT d1.dept_name, d1.range_start, d1.range_end
FROM DepartmentPhoneRanges AS d1
LEFT JOIN DepartmentPhoneRanges AS d2
ON d1.dept_name = d2.dept_name AND d1.range_start = d2.range_end + 1
WHERE d2.dept_name IS NULL
) AS strt
,
(SELECT @rownum := 0) r
ORDER BY dept_name, range_start
) AS oStart
INNER JOIN (
SELECT end.dept_name, end.range_end, @rownum2 := @rownum2 + 1 AS rank2
FROM
(
SELECT d1.dept_name, d1.range_start, d1.range_end
FROM DepartmentPhoneRanges AS d1
LEFT JOIN DepartmentPhoneRanges AS d2
ON d1.dept_name = d2.dept_name AND d1.range_end = d2.range_start - 1
WHERE d2.dept_name IS NULL
) AS end
,
(SELECT @rownum2 := 0) r
ORDER BY dept_name, range_end
) AS oEnd
ON oStart.dept_name = oEnd.dept_name AND oStart.rank = oEnd.rank2
;
注意-由于mySQL中没有ROW_NUMBER()函数(就像SQL Server中一样),我在
OMG Ponies
中使用了这个技巧,“作为替身回答”如果它们是连续的,为什么它们在数据中的起始范围不同呢?@MikeBrant天知道。某人的遗产。它只是数据库中的行。为什么不修改它来合并这些行呢?您是想检查连续行还是只合并那些dept\u name='Sales'
?@MikeBrant我也不知道如何修改它们。这篇文章只是一个例子,实际上这个表有大约30k行。