Найти «региональные» отношения в данных SQL с помощью запроса или службы SSIS - PullRequest
3 голосов
/ 01 марта 2012

Редактировать для пояснения: я собираю данные еженедельно, основываясь на Zip_Code, но некоторые Zip_Codes являются избыточными.Я знаю, что смогу собрать небольшой объем данных и получить избыточные zip_codes, если смогу установить отношения.

Я хочу определить регион почтового индекса по уникальному набору элементов и значений, которые появляются в этом почтовом индексе, чтобы создать «Таблицу регионов»

Я ищунайти связи по почтовому индексу с определенными данными.В конечном счете, у меня есть таблицы, в которых есть аналогичные значения для многих почтовых индексов.

У меня есть данные, подобные:

ItemCode   |Value  | Zip_Code
-----------|-------|-------
1          |10     | 1
2          |15     | 1
3          |5      | 1 
1          |10     | 2
2          |15     | 2
3          |5      | 2
1          |10     | 3
2          |10     | 3
3          |15     | 3

Или, чтобы упростить идею, я мог бы даже преобразовать ItemCode + Value в уникальныйзначения:

ItemCode+
Value    | Zip_Code
A        | 1
B        | 1
C        | 1
A        | 2
B        | 2
C        | 2
A        | 3
D        | 3
E        | 3    

Как видите, Zip_Code 1 и 2 имеют одинаковые отдельные ItemCode и Value.Zip_Code 3, однако, имеет разные значения для определенных ItemCodes.

Мне нужно создать таблицу, которая устанавливает связь между кодами Zip_Code, которые содержат одинаковые данные.

Финальная таблица будет выглядеть примерно так:

Zip_Code | Region
1        | 1
2        | 1
3        | 2
4        | 2
5        | 1
6        | 3
...etc

Это позволитя собираю данные только один раз для каждого уникального региона и получаю zip_code соответствующим образом.

То, что я делаю сейчас:

В настоящее время я использую запрос, аналогичныйобъединение и сравнение с Zip_Code, используя что-то вроде:

SELECT a.ItemCode
      ,a.value
      ,a.zip_code
      ,b.ItemCode
      ,b.value
      ,b.zip_code
FROM mytable as a, mytable as b -- select from table twice, similar to a join
WHERE a.zip_code = 1  -- left table will have all ItemCode and Value from zip 1
  AND b.zip_code = 2  -- right table will have all ItemCode and Value from zip 2
  AND a.ItemCode = b.ItemCode -- matches rows on ItemCode 
  AND a.Value != b.Value
ORDER BY ItemCode

Это ничего не возвращает, если два почтовых индекса имеют одинаковые ItemNum и Value, и возвращает множество различий между двумя zipкоды, если есть различия.

Однако необходимо перейти от ручного процесса к автоматизированному процессу, поскольку я сейчас работаю с более чем 100 zip_codes.

У меня нет большого опыта программированияна определенных языках, поэтому инструменты в SSIS несколько ограничены для меня.У меня есть некоторый опыт использования инструментов Fuzzy, и я чувствую, что в Fuzzy Grouping может быть что-то, что может пролить свет на видимые области, но не могу понять, как его настроить.

У кого-нибудь естьпредложения?У меня есть доступ к SQLServ и связанным с ним инструментам, а также к Visual Studio.Я пытаюсь избежать написания программы для автоматизации этого, так как мои навыки c # относительно нудистны, но я пойму это при необходимости.

Извините за столь многословный: это мой первый Вопрос, и страница, которую ясогласился, чтобы задать вопрос, предложенный для подробного объяснения, и рассказать о том, что я пробовал ... Заранее благодарен за любую помощь, которую я могу получить.

Ответы [ 2 ]

1 голос
/ 02 марта 2012

Демонстрация того, что для всего есть применение, хотя обычно это заставляет меня съеживаться: объединять значения для каждого почтового индекса в одном поле. Сохраните ZipCode и ConcatenatedValues в справочной таблице (PK на одной, UQ на другой). Теперь вы можете оценить, какие почтовые индексы находятся в одном регионе, сгруппировавшись по ConcatenatedValues.

Вот простая функция для объединения текстовых данных:

CREATE TYPE dbo.List AS TABLE
(
Item    VARCHAR(1000)
)
GO

CREATE FUNCTION dbo.Implode (@List dbo.List READONLY, @Separator VARCHAR(10) = ',') RETURNS VARCHAR(MAX)
AS BEGIN
    DECLARE @Concat VARCHAR(MAX)
    SELECT @Concat = CASE WHEN Item IS NULL THEN @Concat ELSE COALESCE(@Concat + @Separator, '') + Item END FROM @List
    RETURN @Concat
END
GO

DECLARE @List AS dbo.List
INSERT INTO @List (Item) VALUES ('A'), ('B'), ('C'), ('D')
SELECT dbo.Implode(@List, ',')
1 голос
/ 02 марта 2012

Дайте этому шанс (я использовал упрощенный пример, но это легко можно расширить).Я думаю, что действительно интересной частью этого кода является рекурсивный CTE ...

;with matches as (
    --Find all pairs of zip_codes that have matching values.
    select d1.ZipCode zc1, d2.ZipCode zc2
    from data d1
        join data d2 on d1.Val=d2.Val
    group by d1.ZipCode, d2.ZipCode
    having count(*) = (select count(distinct Val) from data where zipcode = d1.Zipcode)
), cte as (
    --Trace each zip_code to it's "smallest" matching zip_code id.
    select zc1 tempRegionID, zc2 ZipCode
    from matches
    where zc1<=zc2
    UNION ALL
    select c.tempRegionID, m.zc2
    from cte c
        join matches m on c.ZipCode=m.zc1
                      and c.ZipCode!=m.zc2
    where m.zc1<=m.zc2
)
--For each zip_code, use it's smallest matching zip_code as it's region.
select zipCode, min(tempRegionID) as regionID
from cte
group by ZipCode
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...