2012-01-24 6 views
0

У меня есть две таблицы, как это:Объединение таблиц по значениям, которые не соответствуют

Сводная таблица

ID int 
CityName Varchar(200) 
PopulationCount int 

Таблица данных

ID int 
CityName Varchar(200) 
PopulationCount int 
Longitude float 
Latitude float 

Сводная таблица 800 строк и DataTable имеет 800 000 строк. Каждое CityName в Сводной таблице содержится в таблице данных хотя бы один раз (и нередко несколько раз). Мне нужно создать новую таблицу для хранения каждого из 800 городов из сводной таблицы и их соответствующих широт/долгот из таблицы данных.

Проблема: поле CityName в сводной таблице не является точным совпадением с CityName в таблице данных. Есть небольшие отличия.

Sample Data: 
    Summary Table, CityName: Yarmouth (N.S.) 
    Data Table, CityName: Yarmouth 

Шаблон в выборочных данных выше, не всегда справедливо и то есть разница не всегда кронштейн поэтому я не вижу регулярные выражения и т.д. работает. Я предполагаю, что может существовать файл contains() или как% CityName%, но я не знаю, как правильно их реализовать.

Любая помощь будет принята с благодарностью ...

+3

Хорошо, поэтому условие для JOIN - одна из проблем, но вы также сказали, что в городе может быть более одной записи в таблице данных. Если да, то какую широту и долготу вы хотите разместить в сводной таблице ?, как вы выбираете одну запись по другой? – Lamak

+0

Что вы ожидаете, если в таблице данных для данного города есть несколько * разных * lat/longs? –

+2

OK Здесь вы должны отступить и посмотреть на свой дизайн, который по своей сути неработоспособный. Ибо на вещи посмотреть, сколько городов по имени Колумб находятся в разных местах в США. Город не является уникальным идентификатором, даже если у вас есть правильное имя. Следующее название города должно храниться в одной и только одной таблице, а cityid должен быть во всех связанных таблицах. Если вы установили это с самого начала с правильными отношениями и FKS, у вас не возникло бы этой проблемы. Для этого нет никаких оснований, кроме как исправить вашу модель данных и хранить данные таким образом, чтобы их можно было успешно запросить. – HLGEM

ответ

0

Использование «как» будет выглядеть примерно так:

select * 
from Summary s 
    join Data d on (s.CityName like '%' + d.CityName + '%') or (d.CityName like '%' + s.CityName + '%') 

Но, как вы сказали, что не может захватить все

+0

Спасибо Dan ... Я был на той дороге. Это не закончилось хорошо. – Bagsy

0

Я нахожусь не уверен, что это будет лучший подход, но, учитывая, что это одноразовая работа, как вы подтвердили в комментарии, я бы определенно попробовал следующее:

  1. Создать промежуточную таблицу CityNames с колоннами, как это:

    • StateCode (ваш код состояния),

    • CityNameVariant,

    • CityNameProper.

  2. Заполняем первые две колонки со всеми различными комбинациями StateCode и CityName, найденных в обеих исходных таблиц.

  3. Используя серию ручных обновлений, заполнить CityNameProper столбец с именами зачищенных от различных нерелевантных частей как (N.S.) или , N.S. и т.д., с тем чтобы получить единое унифицированное имя соответствия его различные версий, для каждого города.Таким образом, таблица будет содержать строки, как это:

    StateCode CityNameVariant CityNameProper 
    --------- --------------- -------------- 
    NS   Yarmouth (N.S.) Yarmouth 
    NS   Yarmouth   Yarmouth 
    NS   Yarmouth, N.S. Yarmouth 
    

    заявления Обновление может выглядеть следующим образом:

    UPDATE CityNames 
    SET CityNameProper = SUBSTRING(
        CityNameVariant, 
        1, 
        CHARINDEX('(', CityNameVariant) 
    ) 
    WHERE CityNameVariant LIKE '% (%)' 
    ; 
    UPDATE CityNames 
    SET CityNameProper = SUBSTRING(
        CityNameVariant, 
        1, 
        CHARINDEX(',', CityNameVariant) 
    ) 
    WHERE CityNameVariant LIKE '%, %' 
    ; 
    UPDATE CityNames 
    SET CityNameProper = SUBSTRING(CityNameVariant, …, …) 
    WHERE CityNameVariant LIKE '…' 
    ; 
    
  4. Окончательный запрос сопоставления двух исходных таблиц будет выглядеть примерно так:

    WITH joined AS (
        SELECT 
        s.StateCode, 
        s.CityName, 
        d.PopulationCount, 
        d.Longitude, 
        d.Latitude, 
        rnk = ROW_NUMBER() OVER (
         PARTITION BY s.StateCode, s.CityName 
         ORDER BY d.Population /* or maybe ‘BY Longitude, Latitude’ 
               or ‘BY (SELECT 1)’, it may not matter 
               but in any event it's up to you */ 
        ) 
        FROM Summary s 
        INNER JOIN CityNames c ON s.StateCode = c.StateCode 
              AND s.CityName = c.CityNameVariant 
        INNER JOIN Data d  ON d.StateCode = c.StateCode 
              AND d.CityName = c.CotyNameProper 
    ) 
    --INSERT INTO SummaryWithData 
    SELECT 
        StateCode, 
        CityName, 
        PopulationCount, 
        Longitude, 
        Latitude 
    FROM joined 
    WHERE rnk = 1 
    

То есть сопоставить все города в Summary с этими i n Data и выберите для каждого в первом ряду из последнего.

Смежные вопросы