Dynamic date case statement - sql

I'm using SQL Management Studio 2012.I Have a query output like below. I would like to have a column that looks at the date completed and if it's greater that 2019-01-01 then the exam is'valid' if earlier then 'Renew'. It can't be a hardcoded 2019-01-01, at the turn of the year I would like it to be looking at 2020-01-01 and so on.
Name Exam Date Completed
Matt English 2018-11-26
James Maths 2019-06-02
I would like
Name Exam Date Completed Valid
Matt English 2018-11-26 No
James Maths 2019-06-02 Yes

I think you simply want to know if the year is the same as the current year. That would be:
(case when year(date_completed) = year(getdate()) then 'Yes' else 'No'
end) as valid

This also works, but I don't know if it's more or less efficient than the case statement above:
SELECT IIF(YEAR(date_completed) < YEAR(GETDATE()),'No','Yes') AS valid

Related

Excluding identical returns from ACCESS query when names are equal

In MS ACCESS, I have a table containing names and dates for when a persons yearly exam expires. This exam is valid for 12 months, so the next exam is typically done before all 12 months have expired.
Table, called "Exam", looks like this (in the real table names are unique):
ID Name Dateexp
1 Peter 30/07/2020
2 john 10/09/2020
3 Bob 11/10/2019
4 Peter 25/06/2021
I have a query that shows the persons with a "valid" exam. I looks like this:
SELECT Name As Name, Dateexp As Expiry FROM Overall WHERE Dateexp > now();
It returns:
Name Expiry
Peter 30/07/2020
John 10/09/2020
Peter 25/06/2021
Problem is that "Peter" has done a new exam thereby extending his expiry date from 30/07/2020 to 25/06/21 and I only want the latest one to be shown.
Query should return:
Name Expiry
Peter 25/06/2021
John 10/09/2020
I am truly lost - does anyone have an idea as to how this can be solved?
Thank you!
You can use max and having clause:
Select name, max(dateexp) as dateexp
from overall
Group by name
Having max(dateexp) > now()
If I followed you correctly, you can just use aggregation, and filter with a having clause:
select name, max(dateexp) as expiry
from overall
group by name
having max(dateexp) > now();
This filters on names whose latest expiry date is in the future.

Create a new column in a SQL query with IF/ELSE logic?

I'm working on a query that pulls a list of people who visited a certain location. Part of the location's policy is that if a person hasn't visited within 3 years, they're no longer an active member and would have to re-establish their membership. Normally I just paste my query results into Excel and add a column with a formula that looks at the last visit date and flags whether the person is active or not, but I thought I might try to add that calculation directly to my query and have SQL Server do the work for me. Problem is, I'm not sure about the syntax.
I'd like my end result to look something like this (I typically have my Excel formula just look 3 years back from the date I'm creating the report, so for the purposes of this example, we're looking 3 years back from 12/17/2019):
PersonID LastVisit Active
-------------------------------------
1001 2019-12-01 YES
1002 2014-07-24
1003 2016-12-31 YES
1004 2018-10-12 YES
1005 2016-02-04
1006 2017-09-20 YES
If I'm understanding right from some of the research I've tried to do so far, this would require a CASE statement.
SELECT
PersonID,
LastVisit,
CASE [--not sure what, if anything, goes here--]
WHEN LastVisit > DATEADD(yy,-3,GETDATE()) THEN 'YES'
END AS Active
FROM PersonInfo
ORDER BY PersonID
As it stands now, I've got a couple of syntax errors: incorrect syntax near '>' and incorrect syntax near 'THEN'. Am I at least on the right track? What do I need to do to get this logic to work?
This syntax should work:
(CASE WHEN LastVisit > DATEADD(year, -3, GETDATE()) THEN 'YES'
END) AS Active
By the way, this is called a case expression in SQL.
The only actual issue I see with your code is your square brackets. You start the comment after your first square bracket in the case statement. If you remove the unnecessary stuff or start the comment earlier it should work.
Removing the comment entirely:
SELECT
PersonID,
LastVisit,
CASE
WHEN LastVisit > DATEADD(yy,-3,GETDATE()) THEN 'YES'
END AS Active
FROM PersonInfo
ORDER BY PersonID
Alternatively just start your comment earlier
SELECT
PersonID,
LastVisit,
CASE --[not sure what, if anything, goes here--]
WHEN LastVisit > DATEADD(yy,-3,GETDATE()) THEN 'YES'
END AS Active
FROM PersonInfo
ORDER BY PersonID

SQL Flag consecutive (follow) records

I am relatively new to SQL and I tried to look for a similar question but I was not sure if the question related to my problem or that the answer might have been above skill level.
I think that the question is simple but I am not sure if the solution is simple.
I have the following sql table output
Room Name Time in Room Turnover Date
11 Mansson 740 NA 1/21/2017
11 Klein 841 NA 1/21/2017
11 Klein 1035 28 1/21/2017
I would like to write a query where I can flag fields where the following records are consecutive - Room, Name, Date.
This would flag the last 2 rows where Name is Klein.
Is there a way to do this, if yes can please guide me.
You can add a room/name/date flag using ANSI standard window functions:
select t.*,
(case when count(*) over (partition by room, name, date) > 1
then 1 else 0
end) as HasDuplicatesFlag
from t;

Manually adding a date (month) column to a query in SQL

So essentially I have a table that looks like this:
SalesPerson Target
John 50000.00
Bill 75000.00
Jake 40000.00
I want to add a new column that will make my query look like this:
SalesPerson Target Month
John 50000.00 01/01/14
Bill 75000.00 01/01/14
Jake 40000.00 01/01/14
John 50000.00 02/01/14
Bill 75000.00 02/01/14
Jake 40000.00 02/01/14
And so on.... Obviously the target is a monthly value. The purpose is to be used in a pivot chart in Tableau.
The month field needs to be datetime which should be easy. The only thing coming to mind is to manually do something like:
Convert(datetime, '2014-01-01 00:00:000') as 'MONTH'
and then do that 11 more times and use UNION all each time. This just seems like a lot of text and time. I'm hoping there is a much easier way.
Thanks in advance for all the help!
This is a somehow bizarre scenario, why would you need to repeat every value of your table for every month?. That said, this is one way to do it:
SELECT A.*,
DATEADD(MONTH,B.number,'20140101') AS [Month]
FROM YourTable A
CROSS JOIN (SELECT *
FROM master.dbo.spt_values
WHERE type = 'P'
AND number BETWEEN 0 AND 11) B
Do be aware that this is multiplying the number of rows of your table by 12.

Using SQLite to display repeated and new entries

I have a table with 5 columns, but I really need only information from two. Here is an example of that table, though mine has 1600+ records:
Date Name
2/18 Bob
2/18 Karen
2/19 Fred
2/20 Jared
2/21 Fred
2/22 Bob
2/23 Steve
2/24 Bob
2/25 Jared
I would like to set a date range and find which names were repeats and which were new. For example, if I did this for 2/18-2/21 and 2/22-2/25, I would see that in 2/22-2/25 Bob and Jared were also found in the 2/18-2/21 date range and that Steve was "new." Does anyone have any ideas on a SQLite query to accomplish this task?
You can do this using conditional aggregation, assuming your dates are really in a reasonable format.
select name,
(case when min(date> < STARTDATE then 'RETURNING'
else 'NEW'
end)
from table t
where date between STARTDATE and ENDDATE
group by name;