Postgresql Conditional in where clause - postgresql

I'm using postgres and I want to do a conditional in the where clause.
I want to filter on date1, but if date1 is null, then I want to filter on date2. I tried to following, but it doesn't work. Is there a way to accomplish this?
WHERE
(date1 BETWEEN '2015-01-01' AND '2015-01-31')
OR (CASE WHEN date1 is null THEN date2 BETWEEN '2015-01-01' AND '2015-01-31')

Related

Updating date field with min date from selected dates if they are >= to current_date, except when all dates are >= to current date

I would like to update the contents of the Date1 column to reflect the oldest date in each row, unless the date has already passed (Date1 < current date), in which case i'd like Date1 to be populated with the 2nd oldest date in the row.
ID
Date 1
Date 2
Date 3
Date 4
001
01/14/2022
01/14/2022
01/15/2022
01/16/2022
002
04/15/2019
04/15/2019
01/10/2021
01/10/2021
I am currently using
update mytable t
set date1 = (
select min(date)
from (values (date2), (date3), (date4)) d(dt)
where dt >= current_date
)
The only problem I run into is when all available dates are prior to the current date. In this case it overwrites the value in the date1 column with null, which is not ideal. I'd like the query to leave the date1 field intact in these instances.
Figured it out:
update mytable t
set date1 = coalesce ((
select min(date)
from (values (date2), (date3), (date4)) d(dt)
where dt >= current_date
), date 1);

Increment a date by a interval from a difference of dates - Postgres

Edited: Added information that date1 is a timestamp
I need to increment date but the interval is based on the difference between the date that I want to increment and another date on the table but preserving date1 hours and minutes. E.g.:
Create myTable
( id serial,
date1 timestamp,
date2 date
)
So, if date1 = '2020-01-10 10:30:00'and date2 = '2020-03-08' I need date1 to be '2020-03-08 10:30:00'
Update myTable set date1 = date1+interval (date2-date1)
The syntax demands single quotes between the value (i.e: date + interval '30 days'). How to wrap the result from (date2-date1) in single quotes? I tried many ways without success:
Update myTable set date1 = date1+interval chr(39)||cast((date2-date1) as varchar)|| ' days'|| chr(39)
Update myTable set date1 = date1+interval $$||cast((date2-date1) as varchar)|| ' days'||$$
Update myTable set date1 = date1+interval ''||cast((date2-date1) as varchar)|| ' days'||''
How to I do this properly?
What you want is to set the date part of date1 to date2 and keep the time part:
update myTable
set date1 = date2 + date1::time;
See the demo.

DB2 get max date of four dates query

I want to get greater date from four date columns and fields can be NULL.
Please help me to write a query for this.
Example:
select max(date1, date2, date3, date4) from table A where tag_id='xxxxx'
You can work with unions which combine your query results and then get the max date of the combined columns
Here is the same question asked in another post
Hope that helps you
select max(max_date) from
(select date1 max_date from table A where tag_id='xxxxx'
union all
select date2 from table A where tag_id='xxxxx'
union all
select date3 from table A where tag_id='xxxxx'
union all
select date4 from table A where tag_id='xxxxx')
Here you have:
SELECT
CASE
WHEN date1 >= date2 AND date1 >= date3 THEN date1
WHEN date2 >= date1 AND date2 >= date3 THEN date2
WHEN date3 >= date1 AND date3 >= date2 THEN date3
ELSE date1
END AS RecentDate
FROM table A
WHERE A.tag_id='xxxxx'
Hope it helps,
Did you try your example query?
MAX() (and MIN() for that matter) are a bit unusual....they exists as both an aggregate function operating on multiple rows and a scalar function operating on multiple columns.
The works fine for me on DB2 for IBM i:
select max(dte1,dte2,dte3,dte4) from qtemp.test

Select max date from different columns for a single row

I have this data in a table.
create table pick_max_date
(
student_id int
,date1 datetime
,date2 datetime
,date3 datetime
,date4 datetime
)
insert into pick_max_date
(student_id,date1,date2,date3,date4)values
(1,'2015-06-01','2016-01-01','2014-01-01','2017-01-01')
,(2,'2016-06-01','2017-08-01','2018-01-01','2017-05-06')
,(3,'2013-06-01','2019-08-01','2012-01-01','2012-05-06')
select * from pick_max_date
I need to select the max date for each student as below.
student_id max_date
---------- ----------
1 2017-01-01
2 2018-01-01
3 2019-08-01
what is the most optimised way to select as above. any help is appreciated.
Thanks in advance
Construct a derived table of the columns and select the max from that table,
select student_id,
(
select max(d.d)
from (values(date1),
(date2),
(date3),
(date4)
) as d(d)
) as max_date
from dbo.pick_max_date;
Sergey Gegoyan describes in the following link very efficient four different ways to solve this problem. I would prefer the first one the most:
LINK
Let me know if you found it useful.
SELECT student_id ,
(SELECT Max(v) FROM (VALUES (date1), (date2), (date3)) AS value(v)) as maxdate
FROM pick_max_Date
or
SELECT student_id,b.*
from
pick_max_Date
cross apply
(select max(d)
from
(values(date1),(date2),(date3),(date4))v(d)
)b(maxx)
You can do either the values tables already mentioned, or simply use a case if the columns are static:
select student_id
,(select max(d)
from (values(date1),(date2),(date3),(date4)) as tbl(d)) as MaxDate
,case when date1 >= date2 and date1 >= date3 and date1 >= date4 then date1
when date2 >= date1 and date2 >= date3 and date2 >= date4 then date2
when date3 >= date1 and date3 >= date2 and date3 >= date4 then date3
else date4
end as MaxDate2
from pick_max_date

T-SQL change Time Portion of a DateTime, using another DateTime Time portion

I have a select statement that returns the following:
SELECT
StartDate
,EndDate
FROM
MyTable
And the result returns the following data:
What I want is change the time portion of StartDate using the value from EndDate. So that only the time portion of both dates is the same, taken from EndDate. I have to keep identical, down to milliseconds.
Is it possible using DATEADD function?
Using DateAdd and DateDiff:
SELECT DATEADD(DAY, DATEDIFF(DAY, EndDate, startDate), EndDate) As StartDate,
EndDate
FROM MyTable
I'm adding the days difference between the start date and the end date.
Since the DateDiff have the later date before the earlier date, it returns the days difference as a negative number.
Another option that I'm guessing some people will find more readable is this:
SELECT DATEADD(DAY, -DATEDIFF(DAY, startDate, EndDate), EndDate) As StartDate,
EndDate
FROM MyTable