SQL: Find MIN but greater than a MAX - sql-server

I am working with task history and trying to find two dates attached to the same record: 1) Most recent time a task was approved (max approve); 2)The first submitted date after said approval.
Here is what I have so far:
Select
a.assn_uid,
max(b.ASSN_TRANS_DATE_ENTERED) as LastApprove,
e.LastSubmitted
FROM [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS] a
inner join [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS_COMMENTS] b
on a.ASSN_TRANS_UID = b.ASSN_TRANS_UID
join (select c.assn_uid,
min(d.ASSN_TRANS_DATE_ENTERED) as LastSubmitted
FROM [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS] c
inner join [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS_COMMENTS] d
on c.ASSN_TRANS_UID = d.ASSN_TRANS_UID
where c.ASSN_UID = '499879BC-28B2-E411-8B0A-00059A3C7A00'
and d.[ASSN_TRANS_COMMENT_TYPE_ENUM] = 0
group by c.assn_uid ) e
on e.ASSN_UID = a.ASSN_UID
where a.ASSN_UID = '499879BC-28B2-E411-8B0A-00059A3C7A00'
and b.[ASSN_TRANS_COMMENT_TYPE_ENUM] = 1
group by a.assn_uid, e.LastSubmitted
This is close, however, it gives me the first time ever that the task was submitted. I am sure that I need to use another subquery, I just dont know how to reference a column within the same result.
Here is the task history. Highlighted are the two dates I am trying to show:

I don't know that I could wade through your query in any reasonable amount of time, but to get the row after a particular row, you'd need to do something like this:
create table #submissions (
ID int,
DateAdded datetime,
SubmissionType nvarchar(100)
)
insert #submissions values
(1, '2010-01-01', 'first ever'),
(1, '2010-01-02', 'second'),
(1, '2010-01-03', 'third'),
(1, '2010-01-04', 'approve'),
(1, '2010-01-05', 'first after approve'),
(1, '2010-01-06', 'second after approve'),
(1, '2010-01-07', 'third after approve')
declare #lastApprovalDate datetime
select #lastApprovalDate = MAX(DateAdded)
from #submissions
where
SubmissionType = 'approve'
declare #firstAfterApprovalDate datetime
select #firstAfterApprovalDate = MIN(DateAdded)
from #submissions
where
DateAdded > #lastApprovalDate
select *
from #submissions
where
DateAdded = #firstAfterApprovalDate
drop table #submissions
In general, get the last approval date using MAX(), then get the first date after that date using MIN() where DateAdded > that max, and then select the row at that date. I added Top 1, just in case there happen to be multiple rows at that time. Not sure if that's possible in your data, but just to be safe.

With some help, we figured out we needed an additional min wrapped around the query.
SELECT
final.assn_uid,
final.LastApprove,
min(final.SubmissionDate) FirstSubmitted
FROM
(Select
a.assn_uid,
max(b.ASSN_TRANS_DATE_ENTERED) as LastApprove,
e.SubmittedDates SubmissionDate
FROM [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS] a
inner join [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS_COMMENTS] b
on a.ASSN_TRANS_UID = b.ASSN_TRANS_UID
join (select c.assn_uid,
(d.ASSN_TRANS_DATE_ENTERED) as SubmittedDates
FROM [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS] c
inner join [PRJDEV_ProjectWebApp].[pub].[MSP_ASSIGNMENT_TRANSACTIONS_COMMENTS] d
on c.ASSN_TRANS_UID = d.ASSN_TRANS_UID
where c.ASSN_UID = '499879BC-28B2-E411-8B0A-00059A3C7A00'
and d.[ASSN_TRANS_COMMENT_TYPE_ENUM] = 0
) e
on e.ASSN_UID = a.ASSN_UID
where a.ASSN_UID = '499879BC-28B2-E411-8B0A-00059A3C7A00'
and b.[ASSN_TRANS_COMMENT_TYPE_ENUM] = 1
and e.SubmittedDates > b.ASSN_TRANS_DATE_ENTERED
group by a.assn_uid, e.SubmittedDates) Final
GROUP BY
final.assn_uid,
final.LastApprove

Related

How to generate an automatic INSERT script to a table

I have just started with SQL Server, I don't know if it is with a job, trigger or a procedure, in short, what I need that you can support me is in doing the following: in a database where I store the record of some requirements, which are associated to a state where they can be Completed or Closed, the requirements that are in the Completed state after one week (exactly 7 days) must automatically change status to Closed, but in addition to that I need you to perform the INSERT (automatic) of that record that was made, means that all the data in the row are inserted the same and the only thing that changes is the column that corresponds to state, which in this case would be finished.
The following is the query with which I obtain the records of the requirements longer than 7 days with the status Completed.
SELECT TK_DT_RECORDS.*
FROM TK_HD_TICKETS AS TICKETS
INNER JOIN TK_DT_RECORDS ON TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID
WHERE TK_DT_RECORDS.TK_DT_RECORDS_ID = (SELECT MAX (TK_DT_RECORDS_ID)
FROM TK_DT_RECORDS
WHERE TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID)
AND (TK_DT_RECORDS.TK_CT_STATUS_ID = 'TMN')
AND (TK_DT_RECORDS.ACTIVITY_DATE < DATEADD(DAY, 7, GETDATE()));
Until there I don't know how to perform the automatic INSERT into that table.
TK_CT_STATUS_ID corresponds to the TMN Status Identifier for Completed, CDO for Closed.
UPDATE:
WITH CTE AS
(
SELECT TK_DT_RECORDS.*
FROM TK_HD_TICKETS AS TICKETS
INNER JOIN TK_DT_RECORDS ON TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID
WHERE TK_DT_RECORDS.TK_DT_RECORDS_ID = (SELECT MAX (TK_DT_RECORDS_ID)
FROM TK_DT_RECORDS
WHERE TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID)
AND (TK_DT_RECORDS.TK_CT_STATUS_ID = 'TMN')
AND (TK_DT_RECORDS.ACTIVITY_DATE < DATEADD(DAY, 7, GETDATE()))
)
INSERT INTO TK_DT_RECORDS ([TK_DT_RECORDS_ID], [ACTIVITY_DATE], [CONTENT],[TK_HD_TICKETS_ID], [NOTE], [USER_UPDATE], [TK_CT_STATUS_ID], [TK_BT_EMPLOYEES_ID],[TK_CT_SERVICES_ID], [TK_CT_PRIORITIES_ID], [TK_CT_CATEGORIES_ID], TK_CT_SUBSERVICES_ID])
VALUES ..................;
You have done the hardest part of the work by generating a select query that returns the records that need to be updated. A simple way to turn it into an update statement is to leverage the concept of updatable common table expression, that SQL Server supports:
WITH CTE AS (
SELECT TK_DT_RECORDS.*
FROM TK_HD_TICKETS AS TICKETS
INNER JOIN TK_DT_RECORDS ON TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID
WHERE TK_DT_RECORDS.TK_DT_RECORDS_ID = (SELECT MAX (TK_DT_RECORDS_ID) FROM TK_DT_RECORDS
WHERE TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID )
AND (TK_DT_RECORDS.TK_CT_STATUS_ID = 'TMN')
AND (TK_DT_RECORDS.ACTIVITY_DATE < DATEADD(DAY, 7, GETDATE()))
)
UPDATE CTE SET TK_CT_STATUS_ID = 'CDO'
Edit
If you are looking for an insert statement instead, then you can use the INSERT ... SELECT ... syntax, like:
INSERT INTO TK_DT_RECORDS(
[TK_DT_RECORDS_ID],
[ACTIVITY_DATE],
[CONTENT],
[TK_HD_TICKETS_ID],
[NOTE],
[USER_UPDATE],
[TK_CT_STATUS_ID],
[TK_BT_EMPLOYEES_ID],
[TK_CT_SERVICES_ID],
[TK_CT_PRIORITIES_ID],
[TK_CT_CATEGORIES_ID],
[TK_CT_SUBSERVICES_ID]
)
SELECT
TK_DT_RECORDS.[TK_DT_RECORDS_ID],
TK_DT_RECORDS.[ACTIVITY_DATE],
TK_DT_RECORDS.[CONTENT],
TK_DT_RECORDS.[TK_HD_TICKETS_ID],
TK_DT_RECORDS.[NOTE],
TK_DT_RECORDS.[USER_UPDATE],
'CDO',
TK_DT_RECORDS.[TK_BT_EMPLOYEES_ID],
TK_DT_RECORDS.[TK_CT_SERVICES_ID],
TK_DT_RECORDS.[TK_CT_PRIORITIES_ID],
TK_DT_RECORDS.[TK_CT_CATEGORIES_ID],
TK_DT_RECORDS.[TK_CT_SUBSERVICES_ID]
FROM TK_HD_TICKETS AS TICKETS
INNER JOIN TK_DT_RECORDS
ON TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID
WHERE
TK_DT_RECORDS.TK_DT_RECORDS_ID = (
SELECT MAX (TK_DT_RECORDS_ID)
FROM TK_DT_RECORDS
WHERE TICKETS.TK_HD_TICKETS_ID = TK_DT_RECORDS.TK_HD_TICKETS_ID
)
AND (TK_DT_RECORDS.TK_CT_STATUS_ID = 'TMN')
AND (TK_DT_RECORDS.ACTIVITY_DATE < DATEADD(DAY, 7, GETDATE()))
Please note that this will only work if TK_CT_STATUS_ID is part of all unique keys of your table (including the primary key); otherwise you will get key constraint error when trying to insert new records.
You don't need a cte for this. It is just an update statement. I changed up your query a bit to utilize aliases. When everything is in all upper case it is so difficult to read.
update r
set TK_CT_STATUS_ID = 'CDO'
FROM TK_HD_TICKETS AS t
INNER JOIN TK_DT_RECORDS r ON t.TK_HD_TICKETS_ID = r.TK_HD_TICKETS_ID
WHERE r.TK_DT_RECORDS_ID = (
SELECT MAX(r2.TK_DT_RECORDS_ID)
FROM TK_DT_RECORDS r2
WHERE t.TK_HD_TICKETS_ID = r2.TK_HD_TICKETS_ID
)
AND r.TK_CT_STATUS_ID = 'TMN'
AND r.ACTIVITY_DATE < DATEADD(DAY, 7, GETDATE());

using WHERE clause in INSERT trigger SQL

I am trying to insert a sum of prices from another table.
INSERT INTO Invoice_Of_Supplier (OrderSupplierID, PaymentStatus, Cost)
VALUES (
( SELECT OrderSupplierID FROM inserted),
0,
(SELECT SUM([Price(RUB)]) FROM Car
JOIN OrderOfSupplier_Car AS osc ON osc.CarID=Car.CarID
where osc.OrderSupplierID = (select OrderSupplierID from inserted)))
I have a Car table with fields price , CarID etc;
Order_Of_Supplier table with fields OrderSupplierID, SupplierID;
And Order_Of_Supplier_Car table in which there is a number of cars for each order( fields are CarID, OrderSupplierID)
I need to insert a row in table 'InvoiceOfSupplier' with fields 'OrderSupplierID', PaymentStatus and Cost.
OrderSupplierID and PaymentStatus are ok, but Cost is NULL and I cant understand why.
When i change on osc.OrderSupplierID = 2(getting OrderSupplierID directly) it doesn't work niether.
it Only works, when i remove all conditions like 'WHERE', but in this case it gets the 'Price(RUB)' of all orders, not the one I need.
EDIT:
The problem is that at the moment data was inserted in Order_Of_Supplier there was no data in Order_Of_Supplier_Car.
Try something like this:
INSERT INTO Invoice_Of_Supplier (OrderSupplierID, PaymentStatus, Cost)
VALUES (
( SELECT OrderSupplierID FROM inserted),
0,
(SELECT SUM(column_name) FROM Car
where Car.CarID = OrderOfSupplier_Car.CarID
and OrderOfSupplier_Car.OrderSupplierID in (select OrderSupplierID from inserted))
Why don't you just select from inserted?
INSERT INTO dbo.Invoice_Of_Supplier (OrderSupplierID, PaymentStatus, Cost)
SELECT
i.OrderSupplierID,
0,
SUM(osc.[Price(RUB)])
FROM inserted i
inner join dbo.OrderOfSupplier_Car osc
on osc.OrderSupplierID = i.OrderSupplierID
inner join dbo.Car c
ON c.CarID = osc.CarID
group by i.OrderSupplierID
and I reckon you don't need that join to Car at all
Some questions to you: is this after or instead of trigger? On which table is it?

Multiple value IF statement, to show in select

Any help appreciated,
the code below is from a database which someone made, every time a receipt is made a unique receipt id is issued. same when a reversal is made a new receipt is issued. what links the two are the pay in number. If a reverse is issued, the reverse flag changes on the old receipt to Y and the new one says N. i have my query that select Minimum date and Max data, for receipts returned will have a much later date that when it was first created. The issue is when there is no reverse, it still pulls information as the min and max date are the same. I am fully aware that i need an if statement, but have no idea how to do it since i am new to Databases.
Select distinct r.receipt_date, r.receipt_no, r.doc_no as Payin_No,r.trans_amt,l.location_desc, ct.charge_type_desc,
(select un.first_name + ' ' + un.last_name)as cashier,
r.payee, r.comments, r.reverse_flag, ret1.returned_by, ret1.return_date
from Cashier..receipts as r
inner join Cashier..location as l on r.location_id=l.location_id
inner join [Cashier].[dbo].[charge_type] as ct on ct.charge_type_no=r.charge_type_no
inner join Cashier..user_name as un on un.user_name=(UPPER(r.created_by))
inner join (
select receipt_no as Return_Receipt ,
(select un2.first_name + ' ' + un2.last_name) as returned_by,
created_date as return_date, doc_no as Payin_no,
r1.reverse_flag
from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by))
where doc_no = r1.doc_no
and created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r1.doc_no)) as ret1
on (ret1.Payin_no=r.doc_no)
where r.receipt_date = (select MIN(r1.receipt_date) from Cashier..receipts as r1 where r1.receipt_no = r.receipt_no )
Issue i am having, the return by is the same as created
Desired result
Is this basically what you're trying to do?
-- test data creation, for me
create table receipts (receipt_no int, receipt_date datetime, doc_no int, reverse_flag char(1), returned_by varchar(10), create_date datetime, created_date datetime)
insert into receipts values (1, '1/1/2016', 12345, 'Y', 'John', null, '1/1/2016')
insert into receipts values (2, '2/15/2016', 12345, 'N', null, '2/15/2016', '2/15/2016')
SELECT r.receipt_date, r.receipt_no, r.doc_no, r.reverse_flag, ret1.return_date
FROM receipts r
INNER JOIN (
SELECT doc_no, create_date as return_date
FROM receipts
WHERE reverse_flag = 'N')ret1 on r.doc_no = ret1.doc_no and ret1.return_date > r.receipt_date
WHERE r.reverse_flag = 'Y' and r.doc_no = 12345
If that's your goal, I think you just tack this on to the very end of your query:
and r.receipt_date < ret1.return_date
Edit: Based on your update, I think tack this onto the end:
and convert(date, r.receipt_date) < convert(date, ret1.return_date)
I'm still really not sure what you want.
select *
from ( select doc_no, min(receipt_date) as min_receipt_date
from receipts group by doc_no ) as min_receipt
left outer join ( select doc_no, max(receipt_date) as max_receipt_date
from receipts group by doc_no) as max_receipt
on min_receipt.doc_no = max_receipt.doc_no and
min_receipt.min_receipt_date <> max_receipt.max_receipt_date
for
insert into receipts values (1, '2016-01-01', 12345, 'Y', 'John', null, '2016-01-01');
insert into receipts values (2, '2016-03-15', 12345, 'N', null, '2016-03-15', '2016-03-15');
insert into receipts values (3, '2016-03-15', 123667, 'N', null, '2016-03-15', '2016-03-15');
yields
doc_no min_receipt_date doc_no max_receipt_date
12345 January, 01 2016 00:00:00 12345 March, 15 2016 00:00:00
123667 March, 15 2016 00:00:00 (null) (null)
but it assumes that the return date will never be the same as the original receipt date. I also left off the Y and N flags because I don't see how it's necessary if the min date is always the original purchase date. The other answer here uses the created_date but in your screenshot of the table data, you only show one date so I wrote it assuming only one date (the receipt date). I tested that on MySQL because SQLFiddle was hating on my SQL Server syntax for inserts and I don't have another way to test right now.
This is what i was looking for, figured it out. Thank you Max for opening insights on how i could tackle the problem.
Select distinct r.receipt_date, r.receipt_no, r.doc_no as Payin_No,r.trans_amt,l.location_desc, ct.charge_type_desc,
(select un.first_name + ' ' + un.last_name)as cashier,
r.payee, r.comments, r.cost_centre, r.item, r.programme, r.activity, r.btl_sof, r.reverse_flag, --, ret1.returned_by, ret1.return_date
(case when r.reverse_flag = 'Y' then (select (un2.first_name + ' ' + un2.last_name)from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by)) where created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r.doc_no)) end ) as returned_by ,
(case when r.reverse_flag = 'Y' then (select created_date from Cashier..receipts as r1
inner join Cashier..user_name as un2 on un2.user_name=(UPPER(r1.created_by)) where created_date = (select MAX(created_date)
from Cashier..receipts where doc_no = r.doc_no)) end ) as returned_date
from Cashier..receipts as r
inner join Cashier..location as l on r.location_id=l.location_id
inner join [Cashier].[dbo].[charge_type] as ct on ct.charge_type_no=r.charge_type_no
inner join Cashier..user_name as un on un.user_name=(UPPER(r.created_by))
where r.receipt_date = (select MIN(r1.receipt_date) from Cashier..receipts as r1 where r1.receipt_no = r.receipt_no )

Select 1 of 2 similar records where does not

So I have a table called 'Requests' which stores requests for holidays. I want to try extract certain records from the table (joined with others) with the parameter of the clocknumber. But, if there are two records with the same HolidayID and the last (top 1 desc) is of a certain value - we dont include that in the select!
Request Table [shortened down version of it];
http://i.stack.imgur.com/YY1Gk.png
The stored procedure im using is passed a parameter for the username and joins three other tables,
a 'Holidays' table (Stores information on the holiday from, to etc)
a 'Users' table (contains usernames etc)
a 'RequestType' table (contains the types of requests)
From the image of the table, If you imagine all of those requests belong to the same user, I would want to extract only the records with a requesttype of 1. (the requesttype 1 is holiday request and 2 is holiday cancel). But, if there is a second record with the same holidayID and a requesttype of 2, it does not include that.
So running the query, I would want to only get records with the ID 1 and 2, because the last 2 have the same Holiday ID, and the last of the 2 is with a requesttype to cancel the holiday.
Here is my attempted query;
SELECT Holidays.ID, EmployeeClockNumber, Employees.Name AS EmployeeName, HolidayStart, HolidayEnd, HalfDay, AMPM
FROM Holidays
INNER JOIN Employees ON Employees.ClockNumber = Holidays.EmployeeClockNumber
INNER JOIN Requests ON Requests.HolidayID = Holidays.ID
WHERE EmployeeClockNumber = #ClockNo
AND Requests.Accepted = 1
AND RequestTypeID = (SELECT TOP 1 Requests.ID
FROM Requests
INNER JOIN Holidays ON Holidays.ID = Requests.HolidayID
WHERE Requests.RequestTypeID = (SELECT ID FROM RequestType WHERE RequestType = 'Holiday Request')
AND Holidays.EmployeeClockNumber = #ClockNo
ORDER BY Requests.ID DESC)
ORDER BY ID DESC
Could someone point me in the right direction? Thank you
edit: ive got it working myself!
SELECT Holidays.ID, Holidays.EmployeeClockNumber, Employees.Name AS EmployeeName, Holidays.HolidayStart, Holidays.HolidayEnd, Holidays.HalfDay, Holidays.AMPM
FROM Requests
INNER JOIN Holidays ON Holidays.ID = Requests.HolidayID
INNER JOIN Employees ON Employees.ClockNumber = Holidays.EmployeeClockNumber
WHERE Holidays.EmployeeClockNumber = #ClockNo
AND Requests.Accepted = 1
AND Requests.HolidayID NOT IN (SELECT TOP 1 HolidayID
FROM Requests AS R1
WHERE R1.RequestTypeID <> (SELECT ID FROM RequestType WHERE RequestType = 'Holiday Request')
AND R1.HolidayID = Requests.HolidayID
ORDER BY R1.ID DESC)
SELECT * FROM TAB WHERE requestTypeID = 1
AND holidayID not in (SELECT HolidayID from TAB WHERE requestTypeID = 2)
I would use a partition on the select and then filter on that.
So something like
DECLARE #mtable TABLE (
ID INT
,RequestTypeId INT
,HolidayId INT
,Accepted NVARCHAR(50)
)
INSERT #mtable VALUES (1,1,1,'True')
INSERT #mtable VALUES (2,1,2,'True')
INSERT #mtable VALUES (3,1,3,'True')
INSERT #mtable VALUES (4,2,3,'True')
SELECT * FROM (
SELECT MAX(RequestTypeId) OVER (PARTITION BY HolidayID) AS MaxType
,Id
FROM #mtable
) q
WHERE q.MaxType <> 2

Get all parent rows that do not have a row for current date in child table?

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]
How can I change the above query such that it gives me all MissionId's from table [dbo].[Mission] that do not have a row in table [dbo].[Report] where [dbo].[Report].ReportDate is today?
MissionId is the primary key in table Mission and a foreign key in table Report. So I want to get all missions that do not have a row in table Report for the current date.
I've introduced some aliases to make the query easier to read, and added the needed condition. I've also changed the WHERE clause, not sure if that's required:
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]
This assumes that ReportDate contains dates with the time portions set to midnight. If that's not so, then a slightly more complex query is required:
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() returns the current date and time. I'm using a couple of tricks with DATEADD and DATEDIFF to take that value and turn it into the current date at midnight, and (in the second query) tomorrow's date at midnight.
Second query as a fully runnable query:
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]
Result:
MissionId
-----------
1
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

Resources