SQL: Records on same day but different time - sql

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..

Related

SQL - Select max date lines per column value

I have a table with the following fields:
Risk|Date|Value
---------------
A|2019-04-23|3
A|2019-04-23|5
A|2019-06-12|4
A|2019-06-12|1
B|2019-05-22|7
B|2019-05-22|5
B|2019-03-13|4
C|2019-01-03|3
I would like to get all the lines that accomplish: its date value is the maximum along all the date values of that specific risk. The output would be:
Risk|Date|Value
---------------
A|2019-06-12|4
A|2019-06-12|1
B|2019-05-22|7
B|2019-05-22|5
C|2019-01-03|3
For the risk A, 2019-06-12 is the max date. Thus, all the lines with that date are sent to the output.
For the risk B, 2019-05-22 is the max date. Thus, all the lines with that date are sent to the output.
For the risk C, 2019-01-03 is the max date. Thus, all the lines with that date are sent to the output.
Any suggestion?
Thank you so much!!
use corelated subquery
select t1.* from tbale t1
where t1.date=(select max(t2.date) from table t2 where t1.risk=t2.riks)
A simple way filters in the where clause:
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.risk = t.risk);
Use analytical/windowing function to achieve this. Syntax may vary from database to database, but in Hive, it looks like this:
SELECT
x.risk, x.date, x.value
FROM (
SELECT
risk, date, value,
DENSE_RANK() OVER(PARTITION BY risk ORDER BY date DESC) AS risk_rank
FROM
table_name
) x
WHERE x.risk_rank = 1;
select Risk, date, value
from
(select *, dense_rank() over(partition by risk order by date desc) as K
from Max_date
) as T
where K=1

how to get latest date column records when result should be filtered with unique column name in sql?

I have table as below:
I want write a sql query to get output as below:
the query should select all the records from the table but, when multiple records have same Id column value then it should take only one record having latest Date.
E.g., Here Rudolf id 1211 is present three times in input---in output only one Rudolf record having date 06-12-2010 is selected. same thing with James.
I tried to write a query but it was not succssful. So, please help me to form a query string in sql.
Thanks in advance
You can partition your data over Date Desc and get the first row of each partition
SELECT A.Id, A.Name, A.Place, A.Date FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS rn
FROM [Table]
) A WHERE A.rn = 1
you can use WITH TIES
select top 1 PERCENT WITH TIES * from t
order by (row_number() over(partition by id order by date desc))
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=280b7412b5c0c04c208f2914b44c7ce3
As i can see from your example, duplicate rows differ only in Date. If it's a case, then simple GROUP BY with MAX aggregate function will do the job for you.
SELECT Id, Name, Place, MAX(Date)
FROM [TABLE_NAME]
GROUP BY Id, Name, Place
Here is working example: http://sqlfiddle.com/#!18/7025e/2

SQL: select next available date for multiple records

I have an oracle DB.
My table has ID and DATE columns (and more).
I would like to select for every ID the next available record after a certain date. For only one ID the query would be:
SELECT * FROM my_table
WHERE id = 1 AND date >= '01.01.2018'
(just ignoring the to_date() function)
How would that look like for multiple IDs? And I do want to SELECT *.
Thanks!
We can use ROW_NUMBER here:
SELECT ID, date -- and maybe other columns
FROM
(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM my_table
WHERE date >= date '2018-01-01'
) t
WHERE rn = 1
The idea here is to assign a row number to each ID partition, starting with the earliest date which occurs after the cutoff you specify. The first record from each partition would then be the immediate next date, assuming it exists.

Calculating time between entries in sql

Guys i have a table that has a column named time. It capture the time of each record entry in to the database. I want to query and return another column displaying the duration between one entry and the entry before it. Example, if i store record for john today at 12:00 pm, and then Ali at 1:10 pm, i want another column that will show 01:10:00 (i.e HH:MM:SS).
I understand i can query each column number as follows.
SELECT ROW_NUMBER() OVER (ORDER BY [followuptime]) from [dbo].[FollowUp] .
i wanted to query the max row number AS follows but it fails and return error "windowed...."
SELECT MAX(ROW_NUMBER() OVER (ORDER BY [followuptime])) from [dbo].[FollowUp] .
I wanted to use the DATEDIFF(interval,start_time,end_time); function of sql , but as it is now, I am stuck. Please would appreciate your help or any alternative.
Since SQL-Server 2008R2 does not support LAG/LEAD you will need to do a self join using row_number to get the time from previous row:
WITH OrderedResults AS
( SELECT [id],
[followuptime],
[remark],
RowNumber = ROW_NUMBER() OVER (ORDER BY [followuptime])
FROM [dbo].[FollowUp]
)
SELECT a.ID,
a.FollowUpTime,
a.Remark,
PreviousTime = b.FollowUpTime,
MinutesDifference = DATEDIFF(MINUTE, b.FollowUpTime, a.FollowUpTime)
FROM OrderedResults a
LEFT JOIN OrderedResults b
ON b.RowNumber = a.RowNumber - 1
ORDER BY a.FollowUpTime;
Example on SQL Fiddle
You may not apply MAX to ROW_NUMBER. Use a CTE and query that.
;WITH MyCTE AS
(
SELECT ROW_NUMBER() OVER (ORDER BY [followuptime]) AS RowNum
FROM [dbo].[FollowUp]
)
SELECT MAX(RowNum)
FROM MyCTE

Row with the highest ID

You have three fields ID, Date and Total. Your table contains multiple rows for the same day which is valid data however for reporting purpose you need to show only one row per day. The row with the highest ID per day should be returned the rest should be hidden from users (not returned).
To better picture the question below is sample data and sample output:
ID, Date, Total
1, 2011-12-22, 50
2, 2011-12-22, 150
The correct result is:
2, 2012-12-22, 150
The correct output is single row for 2011-12-22 date and this row was chosen because it has the highest ID (2>1)
Assuming that you have a database that supports window functions, and that the date column is indeed just date (and not datetime), then something like:
SELECT
* --TODO - Pick columns
FROM
(
SELECT ID,[Date],Total,ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY ID desc) rn
FROM [Table]
) t
WHERE
rn = 1
Should produce one row per day - and the selected row for any given day is that with the highest ID value.
SELECT *
FROM table
WHERE ID IN ( SELECT MAX(ID)
FROM table
GROUP BY Date )
This will work.
SELECT *
FROM tableName a
INNER JOIN
(
SELECT `DATE`, MAX(ID) maxID
FROM tableName
GROUP BY `DATE`
) b ON a.id = b.MaxID AND
a.`date` = b.`date`
SQLFiddle Demo
Probably
SELECT * FROM your_table ORDER BY ID DESC LIMIT 1
Select MAX(ID),Data,Total from foo
for MySQL
Another simple way is
SELECT TOP 1 * FROM YourTable ORDER BY ID DESC
And, I think this is the most simple way!
SELECT * FROM TABLE_SUM S WHERE S.ID =
(
SELECT MAX(ID) FROM TABLE_SUM
WHERE CDATE = GG.CDATE
GROUP BY CDATE
)