Select rows with nearest date - sql

I have a SQL statement.
SELECT ID, LOCATION, CODE,MAX(DATE) FROM TABLE1 WHERE
DATE <= CONVERT(DATETIME,'11-11-2012') AND
EXISTS(SELECT * FROM #TEMP_CODE WHERE TABLE1.CODE =#TEMP_CODE.CODE)
AND ID IN (14,279)
GROUP BY ID, LOCATION, CODE,(DATE)
I need rows with the nearest date to the 11-11-2012, but the table returns all the values. What am I doing wrong. Thanks
ID LOCATION CODE DATE
-------------------------------------------------------------------
14 CAR STREET,UDUPI 234 2012-08-08 00:00:00.000
14 CAR STREET,UDUPI 234 2012-08-10 00:00:00.000
14 CAR STREET,UDUPI 234 2012-08-14 00:00:00.000
279 MADHUGIRI 234 2012-08-08 00:00:00.000
279 MADHUGIRI 234 2012-08-11 00:00:00.000
I need to select the row with the max date. The required result is
ID LOCATION CODE DATE
-------------------------------------------------------------------
14 CAR STREET,UDUPI 234 2012-08-10 00:00:00.000
279 MADHUGIRI 234 2012-08-11 00:00:00.000

Remove (DATE) from the GROUP BY Clause.
Change
SELECT ID, LOCATION, CODE,MAX(DATE) FROM TABLE1 WHERE
DATE <= CONVERT(DATETIME,'11-11-2012') AND
EXISTS(SELECT * FROM #TEMP_CODE WHERETABLE1.CODE =#TEMP_CODE.CODE)
AND ID IN ('KBL01005','KBL05020')
GROUP BY ID, LOCATION, CODE,(DATE)
to
SELECT ID, LOCATION, CODE,MAX(DATE) FROM TABLE1 WHERE
DATE <= CONVERT(DATETIME,'11-11-2012') AND
EXISTS(SELECT * FROM #TEMP_CODE WHERETABLE1.CODE =#TEMP_CODE.CODE)
AND ID IN ('KBL01005','KBL05020')
GROUP BY ID, LOCATION, CODE

Try using unambigious date format
SELECT ID, LOCATION, CODE,MAX(DATE) FROM TABLE1
WHERE DATE <= '20121111' AND
EXISTS(SELECT * FROM #TEMP_CODE WHERETABLE1.CODE =#TEMP_CODE.CODE)
AND ID IN ('KBL01005','KBL05020')
GROUP BY ID, LOCATION, CODE
Also see why you need to use unambigious date formats http://beyondrelational.com/modules/2/blogs/70/posts/10898/understanding-datetime-column-part-ii.aspx

No need to use Group by (Date). Try this:
SELECT ID, LOCATION, CODE,MAX(DATE) FROM TABLE1
WHERE DATE <= CONVERT(DATETIME,'11-11-2012') AND
EXISTS(SELECT * FROM #TEMP_CODE WHERE TABLE1.CODE =#TEMP_CODE.CODE)
AND ID IN (14,279)
GROUP BY ID, LOCATION, CODE

Related

Get max date for each from either of 2 columns

I have a table like below
AID BID CDate
-----------------------------------------------------
1 2 2018-11-01 00:00:00.000
8 1 2018-11-08 00:00:00.000
1 3 2018-11-09 00:00:00.000
7 1 2018-11-15 00:00:00.000
6 1 2018-12-24 00:00:00.000
2 5 2018-11-02 00:00:00.000
2 7 2018-12-15 00:00:00.000
And I am trying to get a result set as follows
ID MaxDate
-------------------
1 2018-12-24 00:00:00.000
2 2018-12-15 00:00:00.000
Each value in the id columns(AID,BID) should return the max of CDate .
ex: in the case of 1, its max CDate is 2018-12-24 00:00:00.000 (here 1 appears under BID)
in the case of 2 , max date is 2018-12-15 00:00:00.000 . (here 2 is under AID)
I tried the following.
1.
select
g.AID,g.BID,
max(g.CDate) as 'LastDate'
from dbo.TT g
inner join
(select AID,BID,max(CDate) as maxdate
from dbo.TT
group by AID,BID)a
on (a.AID=g.AID or a.BID=g.BID)
and a.maxdate=g.CDate
group by g.AID,g.BID
and 2.
SELECT
AID,
CDate
FROM (
SELECT
*,
max_date = MAX(CDate) OVER (PARTITION BY [AID])
FROM dbo.TT
) AS s
WHERE CDate= max_date
Please suggest a 3rd solution.
You can assemble the data in a table expression first, and the compute the max for each value is simple. For example:
select
id, max(cdate)
from (
select aid as id, cdate from t
union all
select bid, cdate from t
) x
group by id
You seem to only care about values that are in both columns. If this interpretation is correct, then:
select id, max(cdate)
from ((select aid as id, cdate, 1 as is_a, 0 as is_b
from t
) union all
(select bid as id, cdate, 1 as is_a, 0 as is_b
from t
)
) ab
group by id
having max(is_a) = 1 and max(is_b) = 1;

Second Max Date by ID

I have a table that looks like this
ID Date
123 2/1/2017
123 4/1/2017
123 6/5/2017
123 7/8/2017
456 3/8/2017
456 3/9/2017
456 3/10/2017
Dates are in American format.
I want to pull a list of IDs, with the SECOND max date. So i would like the results to be:
ID Date
123 6/5/2017
456 3/9/2017
I do not know how to do this. I have googled, but with no avail. Any help is greatly appreciated.
I have tried this, but its not working
select *
from (
select ROW_NUMBER() over (partition by ID order by DATE desc ) as 'rowNum', ID, DATE
from table1 ) withRowNum
where rowNum = 2
For SQL Server:
If your dates are varchar, and your current date format is not mdy then you could use set dateformat e.g.
set dateformat mdy;
select *
from (
select ROW_NUMBER() over (
partition by ID
order by convert(date,DATE) desc
) as 'rowNum', ID, DATE
from table1 ) withRowNum
where rowNum = 2

Pull the last updated record based on the value

please assist with my relatively simple query if you can.
I would like a SQL query to pull records where for each ID, the Status = 16 was the latest update date.
From this list:
ID Date Status
000203E 1988-01-01 00:00:00.000 16
000203E 1970-01-01 00:00:00.000 15
000236S 1970-01-01 00:00:00.000 15
000236S 1982-12-15 00:00:00.000 16
000678W 1996-06-05 00:00:00.000 16
000678W 1970-01-01 00:00:00.000 15
000755U 1984-04-16 00:00:00.000 14
000755U 1970-01-01 00:00:00.000 16
Desired output
000203E 1988-01-01 00:00:00.000 16
000678W 1996-06-05 00:00:00.000 16
Thanks in advance!
One method to get the ids is to use aggregation:
select id
from t
group by id
having max(date) = max(case when status = 16 then date end);
If you want the complete rows, you can use in or exists or a join. Or just impute the results:
select id, max(date) as date, 16 as status
from t
group by id
having max(date) = max(case when status = 16 then date end);
Another method to get the complete rows is:
select t.*
from t
where t.status = 16 and
t.date = (select max(t2.date) from t t2 where t2.id = t.id);
SELECT table.*
FROM table
INNER JOIN
(
SELECT id, max(date) max_date
FROM table
WHERE status_id = 16
GROUP BY id
) latest_records
ON
table.id = latest_records.id
AND table.date = latest_records.max_date
SELECT ID, DATE, Status
FROM YOUR_TABLE T1
INNER JOIN (SELECT ID, MAX(Date) DATE
FROM YOUR_TABLE
GROUP BY ID) T2
WHERE T1.ID = T2.ID AND T1.DATE = T2.DATE;

Group by and getting min and date

Declare #dCurrentDate Date = CONVERT (DATE, GETDATE())
Declare #dNextDate Date = DATEADD(month,1,CONVERT (DATE, GETDATE()))
I created a table which contains 10 employee Ids and name as #tbl
then i wrote a query to select min and max date of employee for next 30 days.
SELECT
c.fkEmployeeId as Employee,
e.FullName,c.calendarday
FROM
EmployeeCalendar c
JOIN Employee e
ON (e.pkEmployeeId=c.fkEmployeeId)
GROUP BY c.fkEmployeeId,
e.FullName,
c.calendarday
HAVING
c.CalendarDay BETWEEN #dCurrentDate AND #dNextDate
AND c.fkEmployeeId IN (
SELECT
EmployeeId
FROM
#tbl
)
i am getting result
Id | Name | Date
76 Muhammad 2014-03-05
76 Muhammad 2014-03-12
594 Khan 2014-02-14
but i need
Id | Name | min_date | max_date
76 muhammad 2014-03-05 2014-03-12
594 khan 2014-02-14 2014-02-14
how can i get this.
SELECT id, MIN(record_date), MAX(record_date) FROM table GROUP BY id
SELECT id,
MIN(record_date) AS min_record_date,
MAN(record_date) AS max_record_date
FROM table
GROUP BY id;
try this one....
DECLARE #dCurrentDate DATE = CONVERT (DATE, GETDATE ())
DECLARE #dNextDate
DATE = DATEADD (MONTH, 1, CONVERT (DATE, GETDATE ()))
SELECT
c.fkEmployeeId AS Employee,
e.FullName, MIN(c.calendarday),MAX(c.calendarday)
FROM
EmployeeCalendar c
JOIN Employee e
ON (e.pkEmployeeId = c.fkEmployeeId)
GROUP BY c.fkEmployeeId
HAVING c.CalendarDay BETWEEN #dCurrentDate
AND #dNextDate
AND c.fkEmployeeId IN
(SELECT
EmployeeId
FROM
#tbl)
Try this.
SELECT id,Name
MIN(record_date) AS min_date,
MAN(record_date) AS max_date
FROM table
GROUP BY id,Name
ORDER BY id

Compare values with in a table in SQl

This is MyTable structure
MyTable : ID, Date
Select ID, Date from MyTable
ID Date
50 2013-01-01 00:00:00.000
51 2013-01-02 00:00:00.000
52 2013-01-02 00:00:00.000
I need to get the result like this.
ID Date
50 2013-01-01 00:00:00.000
50 2013-01-02 00:00:00.000
50 2013-01-03 00:00:00.000
51 2013-01-02 00:00:00.000
51 2013-01-03 00:00:00.000
52 2013-01-03 00:00:00.000
How do i get the results ?
Seems like you want to get a list of dates. Of so, then you can use a recursive CTE to get the list of dates:
;with data(id, date) as
(
select id, date
from mytable
union all
select id, dateadd(day, 1, date)
from data
where dateadd(day, 1, date) <= '1/3/2013'
)
select *
from data
order by id
See SQL Fiddle with Demo. This will generate the list of dates for each ID between the current date in your table and the end date that you provide. In my example it is 1/3/2013
I think this will work a bit faster ONLY if there is a CLUSTERED INDEX on the ID column, else bluefeet's solution is fantastic!
SELECT T1.ID
,Date = DATEADD(DAY, -ROW_NUMBER() OVER (PARTITION BY T1.ID ORDER BY (SELECT NULL))+1, '2013-01-03')
FROM MyTable T1
JOIN MyTable T2 ON T1.ID <= T2.ID