#sql #sql-server #sql-server-2008
#sql #sql-сервер #sql-server-2008
Вопрос:
Я пытаюсь написать некоторый SQL, который запрашивает две таблицы и возвращает записи, у которых нет определенного типа записи в другой таблице.
Если таблица 1 является таблицей employee, в которой есть EmpID, имя, фамилия.
и 2-я таблица — это таблица бронирований, в которой есть идентификатор бронирования, EmpID, год
Я хочу найти все записи, в которых нет бронирований на 2014 год.
итак, если таблица employee является:
EMPID Name Surname
1 John Doe
2 Bob Smith
и таблица резервирования
Booking ID Emp ID Year
1 1 2013
2 1 2014
3 2 2012
4 2 2013
Я хочу, чтобы sql только
Комментарии:
1. Как всегда, спасибо за вашу помощь!! как только я опубликовал его и вернулся к SQL Manager, я понял, что я был глуп и запрашивал идентификатор бронирования, когда я хочу удалить все идентификаторы сотрудников, а не идентификаторы бронирования!! Спасибо!!!
2. @Abraham
@Comments
— лучший способ.
Ответ №1:
SELECT * FROM employee
LEFT JOIN Booking ON Booking.empid = employee.empid AND year = 2014
WHERE Booking.empid IS NULL
Ответ №2:
Добавьте WHERE
предложение с NOT EXISTS
проверкой для фильтрации требуемых записей:
SELECT e.EMPID, e.[Name], e.Surname
FROM Employee e
WHERE NOT EXISTS
(SELECT EmpID
FROM Booking b
WHERE b.BookingId = e.EmpId and b.Year = 2014)
Пример скрипта SQL
Для справки, вот сценарий создания / вставки SQL Fiddle:
create table employee(EMPID int, Name varchar(50), Surname varchar(50))
create table booking(BookingID int, EmpID int, Year int)
insert into employee (EMPID, Name, Surname) values(1,'John','Doe')
insert into employee (EMPID, Name, Surname) values(2,'Bob','Smith')
insert into booking(BookingID,EmpID,Year) values(1,1,2013)
insert into booking(BookingID,EmpID,Year) values(2,1,2014)
insert into booking(BookingID,EmpID,Year) values(3,2,2012)
insert into booking(BookingID,EmpID,Year) values(4,2,2013)
Комментарии:
1. Это не сработает. Он хочет сделать противоположное тому, что будет делать внутреннее соединение.
2. Способ включения скрипта SQL. Это здорово.
Ответ №3:
Одним из часто просматриваемых решений является EXCEPT. Это специфичный синтаксис SQL Server, который в основном противоположен ОБЪЕДИНЕНИЮ
SELECT
e.EMPID,
e.Name,
e.Surname
FROM
employee e
EXCEPT
SELECT
e.EMPID,
e.Name,
e.Surname
FROM
employee e
INNER JOIN Booking B
ON e.empID = b.empid
WHERE
b.year = 2014
Другой, также упущенный из виду синтаксис — это != ANY
основное различие между этим и НЕ В том, что вам не нужно беспокоиться о нулевом EmpID при бронировании
SELECT
EmpId, Name
FROM employee e
WHERE empid != ANY (SELECT empid
FROM booking
WHERE year = 2014)
Комментарии:
1. Отличный способ приблизиться к этому. Должно быть естественным для всех, кто любит их диаграммы Венна.
Ответ №4:
select * from employee
where empid not in
(select empid from Booking
where year = 2014)
Конечно, только для иллюстрации, «выбрать *» обычно не очень хорошо, лучше возвращать столбцы, которые вы конкретно хотите…
Однако, если ваша таблица бронирования содержит пустые идентификаторы, вы можете обработать ее чем-то вроде этого:
select * from employee
where empid not in
(select empid from Booking
where year = 2014 and empid is not null)
Комментарии:
1. Что касается вашей заметки, вы можете захотеть взглянуть на этот вопрос на meta.se для возможных альтернатив
2. @Анон, вы ввели нулевой empid в таблицу резервирования, чтобы вызвать сбой. Это не было указано в сценарии OPs. Тем не менее, в интересах полноты я обновил свой ответ, чтобы рассмотреть и это.
3. @ConradFrix — спасибо, я не знал об этой странице, интересно посмотреть дебаты. То, как я это прочитал, я думаю, что я в порядке, принятый ответ предполагает, что уместно предложить OP заменить звездочку соответствующими полями? Конечно, когда я имею дело со своими ассистентами, я бы предпочел слегка подтолкнуть их к подобным вещам, чтобы побудить их подумать об этом самостоятельно. Оцените ссылку и обратите внимание.
4. @PulseLab решения, которые легко ломаются или имеют неожиданные побочные эффекты, являются плохими решениями. Существуют надежные альтернативы (
NOT EXISTS
,LEFT JOIN
,EXCEPT
)5. @PulseLab то, что у вас было абсолютно нормально, и я не хотел предлагать иное. Также я бы написал,
where year = 2014 and empid is not null
а неisnull
просто чтобы избежать возможности того, что кто-то умничает и использует -1 в качестве фактического empid