对于我目前正在开发的应用程序,我有一个需要修复的问题,它面向荷兰语,所以我有一张我可以使用的所有荷兰邮政编码表。
在我的应用程序中,我需要根据引用来构建区域,这是我遇到问题的地方,目前我选择了城市的第一个和最后一个已知的邮政编码,在大多数情况下这很好。对于大多数情况来说这没什么问题,但有时由于邮政编码在另一个城市之前被编号而无法正常工作,因此这意味着在某些情况下一个城市与另一个城市相匹配。
我想做的是从我的桌子上获取我所在城市的所有范围。这是表格的一个小例子(它缺少一些不需要的字段)。
Zipcode | City
--------|-------
2411 AA | Bodegraven
2411 AB | Leiden
2411 AC | Leiden
2411 AD | Bodegraven
2411 AE | Bodegraven
2411 AF | Leiden
2411 AG | Leiden
2411 AH | Bodegraven
根据我当前的查询,Bodegraven中的第一个邮政编码将是2411 AA,最后一个2411 AH,这不是错误的,因为这是存储的内容。 但是我希望我的结果如下:
Start | End
--------|--------
2411 AA | 2411 AA
2411 AD | 2411 AE
2411 AH | 2411 AH
纯MySQL可以生成这个结果吗?
感谢您的时间和回复,如果您有任何疑问,请告诉我们:)
答案 0 :(得分:2)
这在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和max zipcodes)。