基本上我已经为伦敦的所有街道提取了超过500,000条记录。该数据库正在使用SQL Server 2008.对于某些街道,它已正确放置它们,例如'ABBEY TERRACE'和'ABBEY VIEW',但对于像'ABBEY STREET'这样的其他街道,它有许多重复的类似邮政编码条目。
我想做的是保留第一个'ABBEY STREET'(SE1 2AN)和'ABBEY STREET'(SE1 3BU),但删除其他条目。所以基本上它是在查看'5th'字符并删除重复字符。
我将其编入索引,以便删除所有第6个字符的字符,这个字符适用于以W1 1AA开头的邮政编码,但不适用于以W11 1AA开头的邮政编码。
对于以三个字符开头的邮政编码,有没有办法可以通过SQL删除重复项?
表:当地人
Index Street PC
371582 ABBEY STREET SE1 2AN
371583 ABBEY STREET SE1 2DP
371584 ABBEY STREET SE1 3BU
371585 ABBEY STREET SE1 3DW
371586 ABBEY STREET SE1 3ED
371588 ABBEY STREET SE1 3NJ
371589 ABBEY TERRACE SE2 9EY
371590 ABBEY VIEW NW7 4PB
答案 0 :(得分:2)
试试这个 -
<强>查询:强>
DECLARE @temp TABLE
(
[Index] INT
, Street VARCHAR(30)
, PC VARCHAR(10)
)
INSERT INTO @temp ([Index], Street, PC)
VALUES
(371582, 'ABBEY STREET', 'SE1 2AN'),
(371583, 'ABBEY STREET', 'SE1 2DP'),
(371584, 'ABBEY STREET', 'SE1 3BU'),
(371585, 'ABBEY STREET', 'SE1 3DW'),
(371586, 'ABBEY STREET', 'SE1 3ED'),
(371588, 'ABBEY STREET', 'SE1 3NJ'),
(371589, 'ABBEY TERRACE', 'SE2 9EY'),
(371590, 'ABBEY VIEW', 'NW7 4PB')
SELECT t.[Index], t.Street, t.PC
FROM (
SELECT
*
, rn = ROW_NUMBER() OVER (
PARTITION BY Street, CAST(PC AS CHAR(5))
ORDER BY CAST(PC AS CHAR(5))
)
FROM @temp
) t
WHERE rn = 1
<强>结果:强>
Index Street PC
----------- ------------------------------ ----------
371582 ABBEY STREET SE1 2AN
371584 ABBEY STREET SE1 3BU
371589 ABBEY TERRACE SE2 9EY
371590 ABBEY VIEW NW7 4PB
删除声明:
DELETE FROM t
FROM (
SELECT
*
, rn = ROW_NUMBER() OVER (
PARTITION BY Street, CAST(PC AS CHAR(5))
ORDER BY CAST(PC AS CHAR(5))
)
FROM <your_table>
) t
WHERE rn > 1
SELECT *
FROM <your_table>
答案 1 :(得分:2)
以下是allowed formats for a UK Postcode(其中A是任何字母,9是任意数字):
Format Example
AA9A 9AA EC1A 1BB
A9A 9AA W1A 1HQ
A9 9AA M1 1AA
A99 9AA B33 8TH
AA9 9AA CR2 6XH
AA99 9AA DN55 1PT
由于英国邮政编码的所有变体以相同格式(数字字母)结尾,您可以使用以下方式提取邮政编码:
SUBSTRING(PC, 1, LEN(PC) -2)
即。只需删除邮政编码中的最后两个字母即可。然后,您可以通过此部分邮政编码对数据进行分区:
此方法将从示例中获取以下部分列:
Format Example Partial
AA9A 9AA EC1A 1BB EC1A 1
A9A 9AA W1A 1HQ W1A 1
A9 9AA M1 1AA M1 1
A99 9AA B33 8TH B33 8
AA9 9AA CR2 6XH CR2 6
AA99 9AA DN55 1PT DN55 1
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY Street, SUBSTRING(PC, 1, LEN(PC) - 2) ORDER BY PC)
FROM Locals;
然后只是删除那些不是第一行的行:
WITH CTE AS
( SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY Street, SUBSTRING(PC, 1, LEN(PC) - 2) ORDER BY PC)
FROM Locals
)
DELETE CTE
WHERE RN > 1;
<强> Example on SQL Fiddle 强>
注意,您可能需要根据具体要求更改ORDER BY
功能中的ROW_NUMBER()