Select records based on 2 date columns - sql-server

What will be the best script to get the records from a certain table with column createdDate and modifiedDate where modifiedDate is the only nullable column and is equal to date now/current date?
In case that there will be null values from modified date column, the script will get the created date.
The output should get all records with latest created or modified data. I tried these script below:
SELECT *
FROM table
WHERE ISNULL(CONVERT(date, ModifiedDate),
CONVERT(date,CreatedDate)) = CONVERT(date, getdate())
or
SELECT *
FROM table
WHERE CASE WHEN ModifiedDate IS NULL
THEN CONVERT(date, CreatedDate)
ELSE CONVERT(date,ModifiedDate) END = CONVERT(date, getdate())

If you just need this against today (= GETDATE()) this should be simple as this:
SELECT *
FROM tbl
WHERE CAST(CreatedDate AS DATE) = CAST(GETDATE() AS DATE)
OR (ModifiedDate IS NOT NULL AND CAST(ModifiedDate AS DATE)= CAST(GETDATE() AS DATE));
Some thoughts: It is very bad to use functions (here: ISNULL()) in predicats. The engine will not be able to apply existing indexes. Read about sargable. One exception is CAST(SomeDateTime AS DATE) which is sargable.
If you do not need this for any date (just for today), it should be enough to say: This row was created today or it was modified today.
Important Be sure that there are indexes for ModifiedDate and CreatedDate!

Is this what you are looking for?
SELECT
someColumn1,
someColumn2,
CASE
WHEN modifiedDate IS NULL THEN createdDate
ELSE modifiedDate
END AS someDate
FROM someTable

You may use ISNULL() function in TSQL
SELECT *
FROM table
WHERE
ISNULL(CONVERT(date,ModifiedDate), CONVERT(date, CreatedDate)) = CONVERT(date, getdate())

If using function will affect the indexes, kindly try this one if this is efficient.
SELECT *
FROM table
WHERE ModifiedDate IS NOT NULL
AND CONVERT(date,ModifiedDate) = CONVERT(date, getdate()
UNION
SELECT *
FROM table
WHERE ModifiedDate IS NULL
AND CONVERT(date,CreatedDate) = CONVERT(date, getdate()

Related

SAP B1: How to check if new data was inserted in OIVL table

In SAP B1, I wanted to count data that is created 3 hours prior to current time.
I already have this logic
SELECT COUNT(*)
FROM OIVL T0
WHERE T0.CreateDate >= DATEADD(hour, -12, GETDATE())
But the problem is the CreateDate column only contains Date, without time.
It has time but in smallint
Given the discussion in comments about how CreateTime is encoded by SAP B1, you're going to need to compute each row's datetime value to compare it with the current time, e.g.:
create table #Example (
CreateDate date,
CreateTime smallint
);
insert #Example (CreateDate, CreateTime) values ('2020-08-30', 2324);
select
CreateDate,
CreateTime,
CreateDateTime --2020-08-30 23:24:00.000
from #Example
outer apply (
select dateadd(mi, (CreateTime/100)*60+CreateTime%100, cast(CreateDate as datetime)) as CreateDateTime
) Calc
where CreateDateTime >= dateadd(hour, -12, getdate());

Max Date between 2 dates

How can I find the latest date in a column but constrain it between 2 dates
SELECT [Weight]
FROM [weighinevent] w
WHERE [Date] = (SELECT MAX([Date]) WHERE [Date] BETWEEN #StartDate AND #EndDate AND w.[userid] = #userid )
This is what I have. Is that correct?
No, it is not correct. Subqueries need to define the table too from which they are selecting. But you can order by the date and take only the first record
SELECT top 1 Weight
FROM weighinevent
WHERE Date BETWEEN #StartDate AND #EndDate
AND userid = #userid
ORDER BY Date DESC

SQL Server syntax to return a query between 2 given dates

I have an SQL Server table that has a column called statusdate that's an ODBC date/time.
I need to create a SELECT query WHERE statusdate can return a range between 2 dates (a start date and an end date). I've been told to use DATEDIFF in my WHERE statement. Is this correct and what's the syntax?
If you are using SQL Server 2008/2012 and the date datatype you can use between.
select *
from YourTable
where statusdate between #StartDate and #EndDate
If you use datetime I suggest you use >= and < instead to make sure you get all values regardless of the time part.
select *
from YourTable
where statusdate >= #StartDate and
statusdate < dateadd(day, 1, #EndDate)
Update
I've been told to use DATEDIFF in my WHERE statement. Is this correct
No you should not use datediff for this.
and what's the syntax?
Here... but don't use it.
select *
from YourTable
where datediff(day, statusdate, #StartDate) = 0 and
datediff(day, statusdate, #EndDate) = 0
Why don't you just do a BETWEEN?:
SELECT *
FROM YourTable
WHERE statusdate BETWEEN StartDate AND EndDate

Get days from current timestamp in SQL query

I have a table:
ID Timestamp
1 2010-07-27 13:14:00.000
2 2010-08-13 13:14:00.000
3 2010-12-21 13:14:00.000
Now I need to subtract the day from Timestamp column with current getdate() and get the days from it.
You can use DATEDIFF
SELECT DATEDIFF(day, Timestamp, getdate())
FROM YourTable
DATEDIFF
Returns the count (signed integer) of the specified datepart
boundaries crossed between the specified startdate and enddate.
Syntax
DATEDIFF ( datepart , startdate , enddate )
You can use datediff to calculate the difference between datetime values.
declare #T table
(
ID int,
Timestamp datetime
)
insert into #T values
(1, '2010-07-27 13:14:00.000'),
(2, '2010-08-13 13:14:00.000'),
(3, '2010-12-21 13:14:00.000')
select datediff(day, Timestamp, getdate())
from #T
you can use.
CURRENT_TIMESTAMP

SQL Server GROUP BY datetime ignore hour minute and a select with a date and sum value

I have a table with two fields - datetime and int. I want to do a group by on the datetime only on the date ignoring the hour and minute. The SELECT statement should return a date that maps to the sum of the int of a single day.
SELECT CAST(Datetimefield AS DATE) as DateField, SUM(intfield) as SumField
FROM MyTable
GROUP BY CAST(Datetimefield AS DATE)
As he didn't specify which version of SQL server he uses (date type isn't available in 2005), one could also use
SELECT CONVERT(VARCHAR(10),date_column,112),SUM(num_col) AS summed
FROM table_name
GROUP BY CONVERT(VARCHAR(10),date_column,112)
I came researching the options that I would have to do this, however, I believe the method I use is the simplest:
SELECT COUNT(*),
DATEADD(dd, DATEDIFF(dd, 0, date_field),0) as dtgroup
FROM TABLE
GROUP BY DATEADD(dd, DATEDIFF(dd, 0, date_field),0)
ORDER BY dtgroup ASC;
-- I like this as the data type and the format remains consistent with a date time data type
;with cte as(
select
cast(utcdate as date) UtcDay, DATEPART(hour, utcdate) UtcHour, count(*) as Counts
from dbo.mytable cd
where utcdate between '2014-01-14' and '2014-01-15'
group by
cast(utcdate as date), DATEPART(hour, utcdate)
)
select dateadd(hour, utchour, cast(utcday as datetime)) as UTCDateHour, Counts
from cte
Personally i prefer the format function, allows you to simply change the date part very easily.
declare #format varchar(100) = 'yyyy/MM/dd'
select
format(the_date,#format),
sum(myfield)
from mytable
group by format(the_date,#format)
order by format(the_date,#format) desc;

Resources