2014-02-18 4 views
0
SELECT 
    [dbo].[Mission].[MissionId] 
FROM 
    [dbo].[Mission] 
LEFT OUTER JOIN 
    [dbo].[Report] ON [dbo].[Mission].[MissionId] = [dbo].[Report].[MissionId] 
WHERE 
    [dbo].[Report].ReportDate IS NULL 
ORDER BY 
    [dbo].[Mission].[MissionId] 

Как я могу изменить приведенный выше запрос таким образом, что она дает мне все MissionId «S из таблицы [dbo].[Mission], которые не имеют строку в таблице [dbo].[Report] где [dbo].[Report].ReportDate является сегодня?Получите все родительские строки, которые не имеют строки для текущей даты в дочерней таблице?

MissionId является основным ключом в таблице Mission и внешним ключом в таблице Report. Поэтому я хочу получить все миссии, у которых нет строки в таблице Report для текущей даты.

ответ

4

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

SELECT m.[MissionId] 
FROM [dbo].[Mission] m LEFT OUTER JOIN [dbo].[Report] r 
    ON m.[MissionId] = r.[MissionId] 
    AND r.ReportDate = DATEADD(day,DATEDIFF(day,0,GETDATE()),0) 
WHERE r.MissionId IS NULL 
ORDER BY m.[MissionId] 

Это предполагает, что ReportDate содержит даты, времени частей, установленных до полуночи. Если это не так, то чуть более сложный запрос требуется:

SELECT m.[MissionId] 
FROM [dbo].[Mission] m 
WHERE NOT EXISTS(select * from dbo.Report r 
       where r.MissionID = m.MissionID and 
        r.ReportDate >= DATEADD(day,DATEDIFF(day,0,GETDATE()),0) and 
        r.ReportDate < DATEADD(day,DATEDIFF(day,0,GETDATE()),1) 
       ) 
ORDER BY m.[MissionId] 

GETDATE() возвращает текущую дату и время. Я использую пару трюков с DATEADD и DATEDIFF, чтобы принять это значение и превратить его в текущую дату в полночь и (во втором запросе) завтрашнюю дату в полночь.


Второй запрос как полностью работоспособный запроса:

declare @mission table (MissionID int not null); 
insert into @mission (MissionID) select 1 union all select 2; 
declare @report table (MissionID int not null,ReportDate datetime not null); 
insert into @report (MissionID,ReportDate) 
select 2,GETDATE() union all select 1,DATEADD(day,-1,GETDATE()); 

SELECT m.[MissionId] 
FROM @mission m 
WHERE NOT EXISTS(select * from @report r 
       where r.MissionID = m.MissionID and 
        r.ReportDate >= DATEADD(day,DATEDIFF(day,0,GETDATE()),0) and 
        r.ReportDate < DATEADD(day,DATEDIFF(day,0,GETDATE()),1) 
       ) 
ORDER BY m.[MissionId] 

Результат:

MissionId 
----------- 
1 
+0

+1 от меня, это хорошо выглядит. –

+0

при дальнейшем тестировании, вариант 2 не содержит никаких строк. Любая идея почему? – StackTrace

+0

@ SQL.NETWarrior - если вы можете настроить [sqlfiddle] (http://sqlfiddle.com/) с некоторыми примерами данных или добавить некоторые примерные данные на свой вопрос и ожидаемые результаты, вы получите полностью протестированные запросы. Как бы то ни было, я могу составлять только данные, для которых он работает. Я добавляю полный сценарий воспроизведения внизу моего ответа. –

0
select 
    m.MissionId 
from Mission m 
left join Report r 
    on m.MissionId = r.MissionId 
    and day(r.ReportDate) = day(getdate()) 
    and month(r.ReportDate) = month(getdate()) 
    and year(r.ReportDate) = year(getdate()) 
WHERE r.ReportDate is null 
ORDER BY m.MissionId 
Смежные вопросы