2012-05-23 5 views
2

Итак, у меня снова возникает проблема с MS Access, но это, похоже, также является проблемой при попытке подобных запросов в SSMS (SQL Server Management Studio).MS Access Отдельные записи в Recordset

У меня есть набор таблиц, свободно определяется следующим образом:

  1. таблица widget_mfg {идентификатор (целое), имя (NVARCHAR)}
  2. таблица виджет {идентификатор (целое), имя (NVARCHAR) , mfg_id (интермедиат)}
  3. таблица widget_component {идентификатор (целое), имя (NVARCHAR), WIDGET_ID (INT), component_id}
  4. таблица компонент {идентификатор (целое), имя (NVARCHAR), ...} - - В этой таблице имеется ~ 25 столбцов

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

SELECT c.*, wc.widget_id, w.mfg_id 
FROM ((widget_component wc INNER JOIN widget w ON wc.widget_id = w.id) 
INNER JOIN widget_manufacturer wm on w.mfg_id = wm.id) 
INNER JOIN component c on c.id = wc.component_id 
WHERE wm.id = 1 

Предыдущий пример показывает дубликаты любой части, которая содержится в нескольких widget_component списков для разных виджетов.

Я также пробовал делать:

SELECT DISTINCT c.id, c.name, wc.widget_id, w.mfg_id 
FROM component c, widget_component wc, widget w, widget_manufacturer wm 
WHERE wm.id=w.mfg_id AND wm.id = 1 

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

Любая помощь в этом была бы полезной.

Как в стороне, я не очень хорошо разбираюсь в MS Access или SQL вообще. Я знаю основы, но не так уж много.

Edit:

Я просто попробовал этот код, и она работает, чтобы получить все component.id, в то время ограничивая их одной записи каждого. Как я могу использовать результаты этого, чтобы получить список всех остальных данных компонента (компонент. *), Где идентификаторы из первой части используются для выбора этих данных?

SELECT DISTINCT c.part_no 
FROM component c, widget w, widget_component wc, widget_manufacturer wm 
WHERE(((c.id=wc.component_id AND wc.widget_id=w.id AND w.mfg_id=wm.id AND wm.id=1))) 

(постскриптум это, вероятно, не самый лучший способ сделать это, но я все еще учусь SQL.)

ответ

1

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

Существует несколько способов сделать это. IN, вероятно, проще всего написать

SELECT c.* 
FROM component c 
WHERE c.id IN (SELECT c.component_id 
       FROM widget w 
         INNER JOIN widget_component c 
         ON w.id = c.widget_id 
       WHERE w.mfg_id = 123) 

Суб запрос IN находит все составные идентификаторы, которые использует конкретный производитель. Внешний запрос затем выбирает любой компонент.id, который является этим результатом. Не имеет значения, если его один раз или 1000 раз он только получит запись компонента один раз.

Других способов сделать это использует СУЩЕСТВУЕТ суб запроса или использовать соединение для запроса (но тогда вы должны дублирующим его)

+0

Я тестировал это, и он действительно работает. Однако я не понимаю, почему и как это работает. Я хотел бы понять, почему. –

+0

@JimP Я обновил свой ответ, чтобы попытаться объяснить его. –

+0

Думаю, я вижу, что происходит. Подзапрос просто создает набор записей widget_component.component_id, в котором основной запрос в основном тестирует component.id = widget_component.component_id. Вид вроде цикла foreach в php, но с набором записей. Звучит ли это правильно? –

1

Это звучит как компонент -До- виджет отношения один-ко-многим. Следовательно, дубликаты. (то есть один и тот же компонент используется более чем одним виджетами).

Ваш Выбор почти в норме -

SELECT c.*, wc.widget_id, w.mfg_id 

но wc.widget_id вызывает дублированные (за предположения выше).

Так удалить wc.widget_id из SELECT, либо агрегировать его (min, max, count и т.д.). Удаление проще. Не забудьте добавить предложение group by.

Попробуйте это:

SELECT DISTINCT c.*, w.mfg_id 

Также - FWIW, это вообще лучшая практика использовать имена полей, вместо *

+0

я проверить это, и это работает. Кажется, я понимаю, почему wc.widget_id вызывает дубликаты. Я хотел бы знать, почему лучше использовать имена полей вместо. *, Особенно если таблица имеет довольно большое количество доступных полей. –

+0

Проблема с звездочкой связана с тем, как SQL-Server выполняет запрос - как правило, звездочка исключает преимущества производительности при индексировании, вызывая полное сканирование таблицы; и заставляя вас передавать больше данных (поля, которые вам не нужны и т. д.) по соединению и т. д. Другие серверы баз данных решают некоторые проблемы производительности лучше, чем SQL-Server, но кажется, что всегда есть удар против ваша производительность на каком-то уровне. Кроме того, вы будете лучше разрабатывать работу - подумать о своем запросе, о том, что вы намереваетесь сделать, и т. Д. - если вы перечислите поля. FWIW. – Chains

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