2015-03-12 3 views
1

Я новичок пытается учиться и на практике SQL с таблицами на основе этой схемы:SQL-решение с подзапросами?

  • EMPLOYEE - ID, Name

  • ASSIGNMENT - ID, Country, Start, End

Первичные ключи: Employee.ID и все четыре столбца, показанные для r ASSIGNMENT; и ASSIGNMENT.ID является ссылкой на EMPLOYEE.ID. Область начала и конца находится в годах.

Проблема: Я пытаюсь написать запрос, в котором будут отображаться все сотрудники (по имени), где они были назначены на задание в США, сразу после того, как они выполнили задание в Канаде.

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

SELECT 
    E.Name 
FROM 
    EMPLOYEE E 
INNER JOIN 
    ASSIGNMENT A ON E.ID = A.ID 
WHERE 
    (SELECT End FROM ASSIGNMENT 
    WHERE Country = 'Canada') = (SELECT Start FROM ASSIGNMENT 
            WHERE COUNTRY = 'USA') 
GROUP BY 
    E.Name; 

Любая критика в пользу моего понимания моих заблуждений приветствуется. Мои ошибки исходят из комбинации подзапросов в разделе WHERE

В этом подзапросе может быть возвращено не более одной записи.

Возможно, кто-то может показать мне другой способ вычислить это?

Этот запрос проходит проверку в MS Access, так как мне было легко быстро создать базу данных и отношения.

ответ

2

Вместо подзапросов использовать другие присоединиться и добавить ограничения на условие соединения:

SELECT 
    E.Name 
FROM 
    EMPLOYEE E 
INNER JOIN 
    ASSIGNMENT A ON ( E.ID  = A.ID 
         AND A.Country = 'Canada') 
INNER JOIN 
    ASSIGNMENT B ON ( E.ID  = B.ID 
         AND B.Country = 'USA' 
         AND B.Start = A.End ) 
GROUP BY 
    E.Name; 

Update

ОП сообщила об ошибке из MS Access жалуясь композитом условия соединения для выше версия. Однако вы можете безопасно перемещать условия внутреннего соединения в предложение where. Однако промежуточные результаты будут расти, поскольку продукт таблиц создается сначала с меньшими ограничениями и затем фильтруется (хороший оптимизатор запросов может избежать ненужного генерации записей, но я не знаю о возможностях MS Access в этом отношении).

SELECT 
    E.Name 
FROM 
    EMPLOYEE E 
INNER JOIN 
    ASSIGNMENT A ON (E.ID = A.ID) 
INNER JOIN 
    ASSIGNMENT B ON (E.ID = B.ID) 
WHERE 
     A.Country = 'Canada' 
    AND B.Country = 'USA' 
    AND B.Start = A.End 
GROUP BY 
    E.Name; 
+0

Выглядит хорошо! Похоже на более логичный подход. К сожалению, я получаю ошибки в этой версии с помощью Access. Когда скобки скорректированы для нескольких объединений, появляется сообщение об ошибке «AND B.Start = A.End», говоря, что выражение JOIN не поддерживается. – Algorithm

+1

Я немного ржавый writ MSAccess quirks ... слишком занят с _real_ rdbms ;-). См. Обновление для ответа для альтернативного решения. Вы можете также использовать «смешанный режим», т.е. только переместите условие оскорбления в предложение where. – collapsar

+0

Согласен. MSAccess уже показывает свои ограничения в моем кратком опыте. Я переместил ваш исходный код с той же базой данных в MS Studio с SQL Server, и он работал безупречно. Благодаря! – Algorithm

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