Check if input date falls within table of start and end dates - sql

I'd like to run a query to check if an input date falls within any given term dates from a table.
Example table of Term Dates:
<table border="1">
<tr><th>termID</th><th>txtStartDate</th><th>txtFinishDate</th></tr>
<tr><td>37</td><td>2017-09-05 00:00:00</td><td>2017-12-15 23:59:00</td></tr>
<tr><td>38</td><td>2018-01-09 00:00:00</td><td>2018-03-29 23:59:00</td></tr>
<tr><td>39</td><td>2018-04-24 00:00:00</td><td>2018-07-06 23:59:00</td></tr>
<tr><td>40</td><td>2018-09-04 00:00:00</td><td>2018-12-14 23:59:00</td></tr>
<tr><td>41</td><td>2019-01-08 00:00:00</td><td>2019-03-29 23:59:00</td></tr>
<tr><td>42</td><td>2019-04-24 00:00:00</td><td>2019-07-05 23:59:00</td></tr></table>
Given an date, let's say today's date, does it fall between any of the rows' start and end date.
Example code approach
date = now()
for (row in rows):
if date between row.txtStartDate and row.txtEndDate:
return "yes"
I can use between logic with given dates but unsure how to apply this to the entire table.
select case when getdate() between '2019-04-24 00:00:00' and '2019-07-05 23:59:00' then 'yes' else 'no' END
Thanks

Try to use WHERE operator:
SELECT *
FROM YourTable yt
WHERE GETDATE() BETWEEN yt.txtStartDate AND yt.txtEndDate

You need to reference the table's columns instead of hard-coding the values. You do this using the table's alias and the proper column name.
DECLARE #InputDate DATE = '2019-01-05'
SELECT
T.*
FROM
YourTable AS T
WHERE
#InputDate BETWEEN T.txtStartDate AND T.txtEndDate
Using a WHERE clause will filter the rows from the table and only display the ones in which the condition is true. If you move your condition as an expression of a new column (in the SELECT column list) then it will display all rows with this new expression:
DECLARE #InputDate DATE = '2019-01-05'
SELECT
T.*,
IsInputDateBetweenDates = CASE
WHEN #InputDate BETWEEN T.StartDate AND T.EndDate THEN 'Yes'
ELSE 'No' END
FROM
YourTable AS T

You can try with IF EXISTS also as shown below.
If Exists (Select 1 from YourTable where GETDATE() between txtStartDate AND txtEndDate)
Begin
--Your if logic
end
else
begin
--Your else logic
end

Related

iSeries SQL - Use Previous Record Value in JOIN criteria

In my example, I am trying to retrieve records from a transaction file based on the previous calendar work date. The work dates are in a file called CALNDR, the transactions in a file called TRNHST. The logic would be to use the CURRENT_DATE to set the cursor on CALNDR, then retrieve the previous work date which will be used to join to TRNHST. This would be simple enough if done in RPG but I am at a loss with SQL. Thanks, for any input you can provide.
CALNDR
TRNHST
This is even more simple with SQL probably.
You may run these statements as is to check.
LAG function use
WITH
CALNDR (CALDT) AS
(
VALUES
CAST ('2022-07-21' AS DATE)
, CAST ('2022-07-22' AS DATE)
, CAST ('2022-07-25' AS DATE)
)
SELECT C.*
FROM
(
SELECT CALDT, LAG (CALDT) OVER (ORDER BY CALDT) AS LAG_CALDT
FROM CALNDR
) C
-- JOIN TRNHST ...
-- You must keep this expression in WHERE >>OUTSIDE<< of the subselect
-- to get the desired result
WHERE C.CALDT =
CAST ('2022-07-25' AS DATE)
--CAST ('2022-07-24' AS DATE)
;
The problem with LAG is that you can't use it, if you have non-continuous calendar as in your case, and CURRENT_DATE for some day (as 2022-07-24 in the example) doesn't exist there.
BTW, I don't know if it's some problem namely with my IBM i v7.5 or not, but if I move the WHERE clause to the subselect, I get wrong result of the query at all - it doesn't achieve the goal desired here and doesn't return the expected result.
Aggregation function use
WITH
CALNDR (CALDT) AS
(
VALUES
CAST ('2022-07-21' AS DATE)
, CAST ('2022-07-22' AS DATE)
, CAST ('2022-07-25' AS DATE)
)
SELECT C.*
FROM
(
SELECT MAX (CALDT) AS LAG_CALDT
FROM CALNDR
WHERE CALDT <
CAST ('2022-07-25' AS DATE)
--CAST ('2022-07-24' AS DATE)
) C
-- JOIN TRNHST
;
Works disregarding of the presence of CURRENT_DATE in the calendar.
Honestly, if "prior working day" for a given date is something you need. You should consider adding such a column to your calendar table.
While you're at it, might as well add a "next working day".
One of the biggest benefits to a calendar table is the ability to pre-calculate such columns. Thus, greatly simplifying your statements.
Not real sure what LAG does as I have never used it. So, here's another solution using a cross join:
WITH calendar (workdt) AS (
VALUES (CAST('2022-01-01' AS date)),
(CAST('2022-02-01' AS date)),
(CAST('2022-03-01' AS date)),
(CAST('2022-04-01' AS date))
),
orders (orderno, orderdt) AS (
VALUES (1, CAST('2022-01-15' AS date)),
(2, CAST('2022-02-15' AS date)),
(3, CAST('2022-03-15' AS date)),
(4, CAST('2022-04-15' AS date))
)
SELECT *
FROM orders a
CROSS JOIN LATERAL (SELECT max(workdt) prevdt FROM calendar WHERE workdt < a.orderdt) b
The cross join only returns a single row for each record in the calendar file, and that row contains the largest work date less than the order date. LATERAL just lets the sub-query access columns from the outer query.
write an SQL function named calndr_prevWorkDate that returns the previous work date.
Then use that function in the WHERE clause of an SQL SELECT statement to select records from the TRNHST table:
select a.*
from trnhst a
where a.trandate = calndr_prevWorkDate( )
Here is the SQL function.
CREATE OR REPLACE FUNCTION calndr_prevWorkDate(
startDate date default current date )
RETURNS date
language sql
specific calndrf1
SET OPTION datfmt = *ISO, DLYPRP = *YES, DBGVIEW = *SOURCE,
USRPRF = *OWNER, DYNUSRPRF = *OWNER, COMMIT = *CHG
BEGIN
declare vCalDate date ;
declare vSqlCode decimal(5,0) default 0 ;
declare sqlCode int default 0 ;
declare sqlState char(5) default ' ' ;
declare vSqlState char(5) default ' ' ;
declare vErrText varchar(256) default '' ;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
begin
SET vSqlCode = SQLCODE ;
SET vSqlState = SQLstate ;
get diagnostics exception 1 vErrText = message_text ;
end ;
select a.caldate
into vCalDate
from calndr a
where a.caldate < startDate
and dayofweek(a.caldate) not in ( 1, 7)
order by a.caldate desc
fetch first row only ;
return vCalDate ;
END
if all u need is the previous date from a table
you can use something like that
select *
from TRNHST
where Trans_Date =
(
select calendar_Date
from CALNDR
where calendar_Date < current date
order by calendar_Date desc
limit 1
)

Count # of Saturdays given a date range

I have a datetime field and a net field. The Sat Count field is done by =IIf(DatePart("w",Fields!DespatchDate.Value)=7,1,0)
I want to total the count of the Saturdays given a starting date and end date (typically a month).
I tried =Sum(IIf(DatePart("w",Fields!DespatchDate.Value)=7,1,0) but the total is wrong.
I also want to count Saturdays for rest of the month, e.g there's a missing 3rd Saturday in the picture.
I also want to do a total of the Net for Saturdays.
Can you point me in the direction. I can do it in SQL or in SSRS
Considering that we do not have any Input or desired output provided, I am assuming that You just want to count Saturdays in a given range:
Select COUNT(*), SUM(Net)
FROM table
WHERE Day# = 7 AND Date BETWEEN '2021-02-16' AND '2021-02-23'
Assuming you want to count saturdays even if it is not part of your dataset, what you need to do is pad out all your dates for the given range and then join it to your base data set.
This would ensure that it accounts for ALL days of the week regardless of a dispatch event occuring on that date / day.
Below is some SQL code that might help you make a start.
declare #startdate date = '2021-02-01'
declare #enddate date = '2021-02-28'
if OBJECT_ID ('tempdb..#dates') is not null
drop table #dates
;WITH mycte AS
(
SELECT CAST(#startdate AS DATETIME) DateValue
UNION ALL
SELECT DateValue + 1
FROM mycte
WHERE DateValue + 1 < #enddate
)
SELECT DateValue into #dates
FROM mycte
OPTION (MAXRECURSION 0)
select
d.DateValue
, datepart(weekday,d.DateValue) as day_no
,case when datepart(weekday,d.DateValue) = 7 then isnull(t.net,0) else 0 end as sat_net
,case when datepart(weekday,d.DateValue) = 1 then isnull(t.net,0) else 0 end as sun_net
from #dates d
left join your_table t
on d.DateValue = t.some_date
drop table #dates
Since I don't know what your required output is, I cannot summarise this any further. But you get the idea!

How to query on DATE on DATETIME Column in SQL Server?

Here is my table having column(completed_on) with datetime field.
However I need to filter results based on date only.
SELECT * FROM myTable
WHERE completed_on
-- Pass Date Range in condition
Please tyr this
SELECT * FROM myTable
WHERE completed_on BETWEEN 'date1' and 'Date2'
-- Pass Date Range in condition
Another option is-
SELECT * FROM myTable
WHERE completed_on >= '20190701' --Sample start Date
and completed_on < '20190722'
-- This will make sure dates will be inclued less then
-- the given date. You have to pass this with
-- understanding what you want. If you want
-- date 7 to be included, please set the end date to 8

Set MIN value in a column in Teradata

I need to set the minium value in all the column by the elements in the group by. The problem for the table is the column lastupdate,some values have '0001-01-01', so when I apply MIN() it doesn't give me a correct value.
I trying with this code, but doesn't work. I want to have the MIN value by period and coddoc in all the column.
SELECT
period,
coddoc,
(
CASE WHEN MIN(lastupdate)='0001-01-01'
THEN MIN(lastupdate)
ELSE MIN(lastupdate)
END
) as lastupdate
FROM table
GROUP BY period, coddoc;
Thanks for the help.
Just take advantage of the fact that MIN() ignores NULL values:
SELECT
period,
coddoc,
MIN(CASE WHEN lastupdate = '0001-01-01' THEN NULL ELSE lastupdate END) as lastupdate
FROM table
GROUP BY period, coddoc;
NB : as commented by #dnoeth, the CASE expression can be shortened as :
NULLIF(lastupdate, '0001-01-01')
Why not just filter in the where clause?
SELECT period, coddoc, MIN(lastupdate) as lastupdate
FROM table
WHERE lastupdate > '0001-01-01'
GROUP BY period, coddoc;

Selecting Date from a table where the column variable type is Varchar in SQL

Suppose I have database table TABLE1 and there is Column COLUMN1. The variable declaration for that column is set up as VARCHAR(20). Also, the column value can be NULL or EMPTY.
Suppose I have some 'dates' in that column (Format 12/01/2011) and I need a query to retrieve the dates, cannot be NULL or Empty and the dates are upto one year in the past (Suppose current date is 01/25/2012. I need the dates before 01/25/2011).
Please, help.
convert the varchar to a date and then work on it.
SELECT convert(date, column1) as date
from table1
where convert(date, column1) < '01/25/2011'
and date is not null and date <> ''
Why don't you use date instead of a varchar for your date since you are keeping it in that form? If you save your dates in a form of YYYY-MM-DD as a varchar you could even use:
SELECT * FROM table1 WHERE column1 < DATE( "2011-01-01" )
but i would highly suggest you convert it to a date since they are using a similar format to the one you provided
SELECT `COLUMN1`
FROM `TABLE1`
WHERE `COLUMN1` is NOT NULL AND
`COLUMN1` != '' AND
STR_TO_DATE(`COLUMN1`, '%m/%d/%Y') < CURRENT_DATE() - INTERVAL 1 YEAR;
SELECT * FROM TABLE1 WHERE CONVERT(DATE, VC_DATE) < CONVERT(DATE,'01/25/2011')
AND LEN(VC_DATE)>0