Объединение многих (> 20) источников данных с различным приоритетом - PullRequest
1 голос
/ 30 августа 2011

Я давно работаю над этой проблемой и, похоже, не могу найти приемлемого решения.Проблема в том, что у меня есть много разных источников данных (не менее 20), которые я вычеркнул, чтобы получить те же шесть или семь столбцов данных, которые мне нужны.Моя цель - создать «вселенную», включающую все элементы, перечисленные в каждом источнике данных.Большая часть данных указана в нескольких источниках, а некоторые только в одном или двух источниках.Мне нужно следить за тем, какие источники имеют какие предметы, а также.В конечном счете, моя цель - таблица с каждым элементом в «юниверсе» в одном столбце, за которым следует ряд столбцов, отмечающих каждый источник, в котором он был идентифицирован (т.е. столбец для источника 12 получает «x», если источник 12 содержит текущийвещь).Кроме того, есть столбцы, в которых есть некоторая информация об элементах (их официальное название).Все элементы имеют уникальный номер, но имеют разные имена, поэтому в итоговой таблице, которую я создаю, мне нужно перечислить имя из источника с наивысшим приоритетом.Таким образом, если элемент находится в источнике 1, используйте имя, указанное в источнике 1;если нет, но он находится в источнике 2, используйте имя, указанное для элемента в источнике 2;и т. д.

Я работаю над этим в Microsoft Access, и до недавнего времени мне удавалось объединить все мои многочисленные исходные таблицы по уникальному номеру и выполнить большой вложенный оператор Iif, чтобы получитьимя в порядке приоритета источников, например,

Iif(Not Null(Source1.ItemName), Source1.ItemName, 
  Iif(NotNull(Source2.ItemName), Source2.ItemName, 
    Iif(...... ))))

Однако теперь у меня возникла проблема, поскольку я добавлял больше источников.Доступ ограничивает, насколько вложенными могут быть операторы Iif.Итак, я попробовал несколько разных решений.Я пытался с помощью VBA выполнить запрос на выборку для каждой исходной таблицы в порядке приоритета, пока не нашел запись, которая соответствует текущему уникальному номеру, и вернул имя элемента, указанное в источнике с наивысшим приоритетом, в котором он был найден.Проблема в том, что эта функция должна запускаться несколько раз для каждого уникального номера, так как есть несколько свойств в дополнение к имени элемента.Это приводит к очень медленному запросу.

Еще одна альтернатива, которую я попробовал, которая работала хорошо (но позже потерпел неудачу по другой причине, которую я объясню), заключалась в создании самостоятельного соединения.У меня был один запрос (query1) сделать объединение уникального номера, имени элемента и других свойств из всех источников, а также добавить столбец для ранга источника.Затем другой запрос (query2) имел подзапрос, который сгруппировался по уникальному номеру и выбрал минимальный ранг источника, который был внутренне присоединен к query1, чтобы получить остальную часть записи, перечисленной в запросе 1 для источника с самым высоким рейтингом.Однако проблема заключается в том, что в моем последнем запросе мне нужно взять эту информацию и добавить флаги, указывающие, в каких источниках найден элемент, а для этого требуется около 20 левых соединений.Кроме того, в некоторых источниках есть данные, которых нет в других, поэтому я не могу просто добавить эти столбцы в объединение query1.Итак, хотя я решил проблему с несколькими вложенными Iif, у меня все еще есть проблема с требованием слишком большого количества соединений.

Что я могу сделать, чтобы получить итоговую таблицу со всеми свойствами элемента, а также исходными столбцами?

Ответы [ 4 ]

1 голос
/ 30 августа 2011

Чтобы сжать столбцы вместе, вы можете использовать стандартную функцию SQL COALESCE.

Access не поддерживает COALESCE, но если имеет функцию NZ.К сожалению, последний принимает только 1 параметр, а не неограниченное число, как COALESCE.

Тем не менее, если вы хотите, чтобы все в одном столбце, вы можете сделать большой UNION, как это.

 SELECT a AS OneColumnToRuleThemAll FROM (
  SELECT col1 as a FROM a
UNION
  SELECT col2 as a FROM b
UNION 
  SELECT ....) S

Это поместит все в один столбец.

0 голосов
/ 31 августа 2011

Я бы сделал это:

SELECT UniqueNumber, Name, 1 as TablePriority FROM Table1
  UNION ALL
SELECT UniqueNumber, Name, 2 as TablePriority FROM Table2
  UNION ALL
SELECT UniqueNumber, Name, 3 as TablePriority FROM Table3
  UNION ALL
SELECT UniqueNumber, Name, 4 as TablePriority FROM Table4
  UNION ALL
SELECT UniqueNumber, Name, 5 as TablePriority FROM Table5
  etc
ORDER BY TablePriority DESC
0 голосов
/ 31 августа 2011

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

1) Мой единственный объединенный запрос (query1 - это то, что я назвал выше) все еще имел уникальные числа, имена элементов, общие свойства, имя источника и флаг источника (мы используем его как индикатор того, был ли он новым для Вселенная или нет).

2) Был создан новый запрос кросс-таблицы (я назову его query1_crosstab) с заголовком строки в качестве уникального номера, заголовком столбца в качестве имени источника и значением (свойством кросс-таблицы) в качестве флага источника. Альтернатива - установить значение равным count (item_name), которое поместит 1 в места, где у источника был соответствующий Item, или сделать Iif (count (item_name) = 1, "x", null) равным вместо этого поставьте x (что мы предпочитаем делать)

3) Был сделан новый запрос на группировку, который выполнял те же действия, что и запрос2 выше, а именно: группировка по уникальному номеру и выбор минимального номера источника и повторное соединение с запросом объединения1 для получения имен элементов из источников с самым высоким рейтингом.

4) К последним новым запросам присоединились 2) и 3) на основе уникального номера, так что все общие свойства, а также информация о присутствии каждого элемента в каждом из источников были перечислены в запросе.

5) Наконец, я мог присоединить этот запрос к любой из исходных таблиц (только 2), у которых были дополнительные свойства, не общие для всех таблиц. В качестве альтернативы на первом шаге (объединение) можно было бы добавить столбцы для включения всех свойств, а столбцы, отсутствующие в источнике, просто имели бы нулевые значения.

Надеюсь, это кому-нибудь поможет!

0 голосов
/ 30 августа 2011

Как насчет 2 шагов.На первом этапе используйте объединение, чтобы объединить все записи в одну таблицу, имеющую все общие столбцы, включая уникальный идентификатор, приоритет, затем имя и другие.Это не должен быть запрос на вставку, поэтому вам не нужна фактическая таблица.

Это не даст вам каждый источник в виде столбца да / нет, но у вас будет одна строка на источникдля каждого уникального идентификатора, который может быть таким же хорошим.

Если вы хотите, чтобы имя верхнего приоритета отображалось для каждой строки, вы можете выполнить выбор с помощью подзапроса для столбца Имя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...