1

基本上我已经提取了伦敦的所有街道,其中有超过 500000 条记录。该数据库使用的是 SQL Server 2008。对于某些街道,它已正确放置它们,例如“ABBEY TERRACE”和“ABBEY VIEW”,但对于“ABBEY STREET”等其他街道,它有许多类似邮政编码的重复条目。

我想做的是保留第一个“ABBEY STREET”(SE1 2AN)和“ABBEY STREET”(SE1 3BU),但删除其他条目。所以基本上它正在查看“第 5 个”字符并删除重复项。

我对此进行了索引,以便删除所有“6th”字符,该字符适用于以 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
4

2 回答 2

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>
于 2013-06-03T12:34:54.520 回答
2

以下是英国邮政编码的允许格式(其中 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;

SQL Fiddle 示例

请注意,您可能需要根据您的确切要求更改函数ORDER BY内部ROW_NUMBER()

于 2013-06-03T12:46:12.013 回答