对于我目前正在开发的一个应用程序,我有一个小问题需要解决,它是面向荷兰语的,所以我有一个表,列出了我可以使用的所有荷兰语邮政编码。
在我的应用程序中,我需要建立基于cites的区域,这是我遇到问题的地方,目前我选择了一个城市的第一个和最后一个已知的邮政编码,这在大多数情况下是可以的。这在大多数情况下是可以的,但有时这并不正确,因为邮政编码在另一个城市之前编号,所以这意味着在某些情况下,一个城市与另一个城市匹配。
我想做的是从我的桌子上取下我所在城市的所有范围。这是这个表的一个小例子(它缺少一些不需要的字段)。Zipcode | City--------|-------2411 AA | Bodegraven2411 AB | Leiden2411 AC | Leiden2411 AD | Bodegraven2411 AE | Bodegraven2411 AF | Leiden2411 AG | Leiden2411 AH | Bodegraven
在我当前的查询中,Bodegraven中的第一个zipcode是2411aa,最后一个是2411ah,这不是交错错误的,因为这是存储的内容。
不过,我希望我的结果如下:Start | End--------|--------2411 AA | 2411 AA2411 AD | 2411 AE2411 AH | 2411 AH
纯MySQL是否可以生成此结果?
感谢您的时间和回复,如果您有任何问题,请告诉我:)
最佳答案
这在MySQL中非常尴尬,但这是可能的。
首先,我们需要一种动态定义某种“组”标识符的方法,这种标识符随着城市从一行到另一行的变化而递增。我们可以用MySQL user-defined variables来完成。
SELECT zipcode,
@groupid:=IF(city=@prev_city,@groupid,@groupid+1) AS groupid,
@prev_city:=city AS city
FROM MyTable, (SELECT @groupid:=0) AS _init
ORDER BY zipcode;
+---------+---------+------------+
| zipcode | groupid | city |
+---------+---------+------------+
| 2411 AA | 0 | Bodegraven |
| 2411 AB | 1 | Leiden |
| 2411 AC | 1 | Leiden |
| 2411 AD | 2 | Bodegraven |
| 2411 AE | 2 | Bodegraven |
| 2411 AF | 3 | Leiden |
| 2411 AG | 3 | Leiden |
| 2411 AH | 4 | Bodegraven |
+---------+---------+------------+
现在我们可以在派生表子查询中使用它,并在每个组中获取MIN()和MAX()值:
SELECT MIN(zipcode) AS Start, MAX(zipcode) AS End
FROM (
SELECT zipcode,
@groupid:=IF(city=@prev_city,@groupid,@groupid+1) AS groupid,
@prev_city:=city AS city
FROM MyTable, (SELECT @groupid:=0) AS _init
ORDER BY zipcode
) AS t
WHERE city = 'Bodegraven'
GROUP BY groupid;
+---------+---------+
| Start | End |
+---------+---------+
| 2411 AA | 2411 AA |
| 2411 AD | 2411 AE |
| 2411 AH | 2411 AH |
+---------+---------+
不幸的是,
WHERE city='Bodegraven'
的条件必须在外部查询中。子查询必须通过读取所有行(而不仅仅是Bodegraven的行)来生成分组。所以它必须扫描很多行(也许您可以将Bodegraven限制为min zipcodes和max zipcodes)。