Updating a table column with the 2nd oldest date in a row? - sql

I would like to update the contents of the Date 1 column to reflect 2nd oldest date each row. The table has thousands of rows and ~15 columns, only a handful of which are dates. I've used the least funtion in the past to update this column with the oldest date in each row, but I can't figure out how to update it with the 2nd oldest date(1/15/2020 for row 1 and 04/15/2020 for row 2 in this instance). Any help would be greatly appreciated.
ID
Date 1
Date 2
Date 3
Date 4
001
01/14/2020
01/15/2020
01/16/2020
002
04/15/2020
03/20/2020
06/16/2020

The simplest option might be to unpivot:
select t.*, d.date
from mytable t
cross join lateral (
select date
from (values (t.date2), (t.date3), (t.date4)) d(date)
order by d.date
limit 1 offset 1
) d
If you wanted an update statement:
update mytable t
set date1 = (
select date
from (values (date2), (date3), (date4)) d(date)
order by d.date
limit 1 offset 1
)
Demo on DB Fiddle

Related

Get highest value from column in where clause

I have table:
id date day
2 21-07 1
2 10-07 3
2 11-07 2
I need to get date which has highest day, in current example it should be 10-07.
Next query works fine, but is there way to make it more optimised?
SELECT date
FROM (SELECT date, MAX(day)
FROM some_table
WHERE id = 2
GROUP BY date
LIMIT 1) x
I would not suggest a where clause. Just use:
select date
from some_table
where id = 2
order by day desc
limit 1;

How can I iterate a date column to check for criteria in SQL?

In a SQL Server 2008 database, I'm trying to identify each ID that has corresponding dates that meet the following criteria:
Are any 2 dates within each ID >= 3 months apart?
Are those same 2 dates <= 24 months apart?
I can do a comparison on the next row, but that doesn't tell me if rows 1 and 3 meet the criteria, or rows 5 and 7, etc.
Here's the table structure (there are around 100,000 rows in the actual table):
select ID, Date from #tmp;
ID Date
ID1 7/2/2016
ID1 10/19/2016
ID1 1/21/2017
ID1 7/19/2017
ID2 11/26/2015
ID2 2/10/2016
ID2 5/23/2016
ID3 6/15/2017
ID3 6/30/2017
So here ID1 and ID2 both have dates meeting the criteria, but the dates for ID3 don't meet the 1st criteria (being 3 months apart).
Here's the self-join I've tried so far:
with NextDateTable as
(
select
ID
,Date
,rn=rank() over (partition by ID order by Date asc)
from #tmp
)
select
a.ID
,a.Date
,NextDate=b.Date
into #tmp2
from NextDateTable a
left join NextDateTable b on a.ID=b.ID and b.rn=a.rn+1
order by ID,Date
;
This gives me a table with the next date in a new column, so I can do the following datediff:
select
ID
,Date
,NextDate
,case
when ((Date is not null) and (NextDate is not null))
and
datediff(mm,Date,NextDate)>=3
and
datediff(mm,Date,NextDate)<=24
then 1
else 0
end as Check
into #tmp3
from #tmp2
;
The problem with this is that it only checks consecutive rows, and it doesn't check every row against each other row within the same ID.
Any suggestions would be greatly appreciated!
Your question simplifies to asking if the total span of the dates is between 3 and 24 months. You can simply do:
select id
from #tmp
group by id
having max(date) >= dateadd(month, 3, min(date)) and
max(date) < dateadd(month, 24, min(date));
Note that if you are asking about adjacent dates, then that is another question, not this one. Ask a new question if that is what you really intend.

SQL: Records on same day but different time

Sample data:
2015-10-09 17:06:54
2015-01-05 11:04:12
2015-01-05 11:04:13
2015-01-09 14:52:19
Hi, I am trying to get a list of records of date + time with a condition: If same date, get the earliest record.
I know this can be easily done by substr() to only the date, but I do need the time too.
Please see the data above: I do not want the 3rd record down because it is a duplicate date but a later time.
How should I do this? Thanks so much for your help!
In MS SQL 2005+, you can try this:
SELECT *
FROM (
SELECT *,
RANK() OVER(PARTITION BY CAST(DateTime_Column AS DATE) ORDER BY DateTime_Column DESC) AS R
FROM Your_Table) AS Tb
WHERE R = 1
If you want to select 1 row for each day, you can use ROW_NUMBER() instead of RANK()
In Oracle, you can change CAST(DateTime_Column AS DATE) to TRUNC(DateTime_Column)
This will display row with later date_time for a specific date.
SELECT T1.*
FROM
table T1 INNER JOIN table T2
ON DATE(T1.date_time) = DATE(T2.date_time)
AND T1.date_time > T2.date_time GROUP BY DATE(T1.date_time)
Hope this helps..

Need a SQL query to get a single, max date when the max date is not unique

My apologies if this has been asked and wasn't able to find this. I've searched for a long time, with no luck.
My table is named RESULT -
DATE TEST_NUM RESULT_NUM
11/16/2010 09:27:11 AM 123456 123111
11/16/2010 09:27:11 AM 123456 123222
11/16/2010 09:27:11 AM 123456 123333
For a given TEST_NUM, I only want to return the max date just one time, and it doesn't matter what the other column entries are -
11/16/2010 09:27:11 AM 123456 123111
SELECT RESULT.DATE,
RESULT.RESULT_NUM,
RESULT.TEST_NUM
FROM RESULT
WHERE RESULT.TEST_NUM = 123456
AND RESULT.DATE = (SELECT MAX(R1.DATE)
FROM RESULT R1
WHERE r1.TEST_NUM = RESULT.TEST_NUM)
But as you guessed, I don't get 1 result - I get all three. I've tried everything! Please help this newbie!
To get the maximum date:
SELECT MAX(RESULT.DATE) FROM RESULT
To get an entire row for any one of the rows that hold the maximum date:
SELECT * FROM
(
SELECT *
FROM RESULT
WHERE RESULT.TEST_NUM = 123456
ORDER BY RESULT.DATE DESC
)
WHERE rownum = 1
UPDATE : -
select max(DATE) from RESULT where RESULT.TEST_NUM = 123456 group by RESULT.TEST_NUM
Here is an example -
select id,max (date_column) from your_table group by id
where id is the column you want the values for max date for, this will give you max date for each of the unique entries for id in that table out of the many date entries, since what I understood was that you have multiple dates and want the max.
Why won't this work
SELECT MAX(DATE) FROM TABLE
SELECT date_column FROM table GROUP BY date_column HAVING COUNT(*)>1 ORDER BY date_column DESC LIMIT 1
This will return the highest date_column ( ORDER BY date_column DESC ) that is not unique ( HAVING COUNT(*) > 1 )
select distinct max(date_column)
into variable
from table
where condition;
Adding the distinct will ensure that if the data is the same then it will only return one record.

Update row only where max date

I have the following data
Date Week ID Tot_Seconds O_Seconds Week_ID
8/14/2011 12:00:00 AM 5823 22180 170043 26043 18
8/21/2011 12:00:00 AM 5824 22180 126471 0 18
I am trying to update a column in another table the value of O_Seconds,where the week and ID match, but i would only like to update where max(date) for each Week. The reason, is the table with the data source has dates by week, where the the table I will update is daily, and using the query I currently have, it updates for example 26043 for all days where id and week match, skewing my future queries where I will sum the values of those columns.
Is there any way to just update the max date?
Something like this
The derived table is used to get the 1st row per week/ID
UPDATE
O
SET
SomeCol = S.O_Second
FROM
OtherTable O
JOIN
(
SELECT
Week, ID, O_Second,
ROW_NUMBER() OVER (PARTITION BY Week, ID ORDER BY Date DESC) AS rn
FROM
ThisTable
) S ON O.Week = S.Week AND O.ID = S.ID
WHERE
S.rn = 1
For SQL Server 2000 and earlier you need an aggregate. See DBA.SE for more