I have a table with data and I am trying to find max date verified
Create table staging(ID varchar(5) not null, Name varchar(200) not null, dateverified datetime not null,dateinserted datetime not null)
ID,Name,DateVerified,DateInserted
42851775,384,2014-05-24 08:48:20.000,2014-05-28 14:28:10.000
42851775,384,2014-05-28 13:13:07.000,2014-05-28 14:36:12.000
42851775,a1d,2014-05-28 09:17:22.000,2014-05-28 14:36:12.000
42851775,a1d,2014-05-28 09:17:22.000,2014-05-28 14:28:10.000
42851775,a1d,2014-05-28 09:17:22.000,2014-05-28 14:29:08.000
42851775,bc5,2014-05-28 09:17:21.000,2014-05-28 14:29:08.000
42851775,bc5,2014-05-28 09:17:21.000,2014-05-28 14:28:10.000
42851775,bc5,2014-05-28 09:17:21.000,2014-05-28 14:36:12.000
I want to display max dateverified for each keyid i.e.
42851775,384,2014-05-28 13:13:07.000,2014-05-28 14:36:12.000
42851775,a1d,2014-05-28 09:17:22.000,2014-05-28 14:36:12.000
42851775,bc5,2014-05-28 09:17:21.000,2014-05-28 14:29:08.000
SELECT i.[ID],i.name,i.dateinserted,r.maxdate
FROM (select id,name,max(dateverified) as maxdate from
[dbo].[staging] where id=42851775 group by id,name) r
inner join
[dbo].[staging] i
on r.id=i.id and r.jobpostingurl=i.jobpostingurl and r.maxdate=i.dateverified
group by i.id,i.jobpostingurl,r.maxdate
I get an error,dateinserted is invalid as it is not contained in group by clause. But if I add it in group by clause I get all 8 records. How to handle this?
Thanks
R
SELECT
KeyID,
MAX(yourDate)
FROM
Staging
GROUP BY
KeyID
If you want additional information join this to another table for instance:
SELECT
b.KeyID,
a.dateinserted,
b.TheDate
FROM YourTable a
INNER JOIN
(
SELECT
KeyID,
MAX(yourDate) AS TheDate
FROM
Staging
GROUP BY
KeyID
) b
ON
b.KeyID = a.KeyID
If you need to get the dateinserted you can use a cte and join it back to the original table:
WITH cte
AS ( SELECT [ID] ,
name ,
MAX(dateverified) AS dateverified
FROM [dbo].[staging]
GROUP BY ID ,
name
)
SELECT cte.[ID] ,
cte.NAME ,
cte.dateverified ,
s.Dateinserted
FROM cte
INNER JOIN dbo.staging s ON cte.[ID] = s.[ID]
AND cte.NAME = s.NAME
AND cte.dateverified = s.dateverified
Related
I have a sql server table showing the IDs and their previous IDs,
create table test2 ( ID varchar(10) ,
Pre_ID varchar(10)
)
insert into test2 values ('e','d')
, ('d','c')
, ('c','b')
, ('b','a')
, ('a',null)
, ('r','q')
, ('q','p')
, ('p',null)
the table is like this:
The result should be like this:
I have successfully got the levels using a recursive cte, but could not get the correct group for them. can anyone help? Thanks.
This is my code:
with cte as (
select id, Pre_ID, level
from #temp2
where Pre_ID is null
union all
select t2.id, t2.Pre_ID, t2.level
from cte
inner join #temp2 t2
on t2.Pre_ID=cte.id
)
select * from cte
order by id
What you need to do is start with the first level and add a ROW_NUMBER to that, then join all further levels recursively:
with cte as (
select id, Pre_ID, level, row_number() over (order by ID) as grp
from #temp2
where Pre_ID is null
union all
select t2.id, t2.Pre_ID, t2.level, cte.grp
from cte
inner join #temp2 t2
on t2.Pre_ID=cte.id
)
select * from cte
order by id;
Hi can you please take a look why my query is not returning distinct record. i want result with following condition OE1='SCHEDCHNG', need only recent records per orderid or ordernum means only one record per ordernum or orderid and also dropdate is null. My query is as below
select DISTINCT TOP 100 OE.ORDERID,OE.ID,OE.ORDERNUM,OE.OE4 from OrderExports OE
inner join (
select ORDERNUM, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm
on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG' AND O.DROPDATE is null
Pretty sparse on details here but I think you are wanting something along these lines.
with SortedResults as
(
select OE.ORDERID
, OE.ID
, OE.ORDERNUM
, OE.OE4
, ROW_NUMBER() over(partition by OE.ORDERID, OE.ORDERNUM order by OE.OE4 desc) as RowNum
from OrderExports OE
inner join
(
select ORDERNUM
, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG'
AND O.DROPDATE is null
)
select ORDERID
, ID
, ORDERNUM
, OE4
from SortedResults
where RowNum = 1
You can try using max and group by as below :
SELECT a.ID, max(a.ORDERID) as OrderID, max(a.ORDERNUM) as OrderNum,MAX(OE.OE4) as OE4 FROM
(
--your query
) a
group by a.ID
I am using following query and it displays following result
Query
SELECT
Id,
COUNT(Id) AS Cnt,
VehNo,
VehName,
ValidTo,
IMIE,
dr.DriD,
DriName,
MAX(SignalDateTime) SignalDateTime,
MAX(DateTime) DateTime
FROM tbl_gpsData gps
LEFT JOIN tbl_Veh eq
ON eq.ID = gps.VehID
LEFT JOIN tbl_DriMaster dr
ON dr.DriID = gps.DriID
GROUP BY ID,
VehNo,
VehName,
ValidTo,
IMIE,
dr.DriID,
DriName
ORDER BY ID ASC
I get the following result after execution but as highlighted in image i get 4 records for same vehid EQM0000009 and some other Vehids because the driID(6 th column.'DRV0000100' and so on ) is different.
I want only one record for EQM0000009 which has maximum datetime value out of 4 records . Datetime is the last column in image. How could i do that grouping within grouping?
Below query will help you
select Id,count(Id) as Cnt,VehNo,VehName,ValidTo,IMIE
,dr.DriD,DriName
,MAX(SignalDateTime)SignalDateTime,MAX(DateTime) [DateTime]
into #temp
from tbl_gpsData gps left join tbl_Veh eq
on eq.ID=gps.VehID
left join tbl_DriMaster dr on dr.DriID=gps.DriID
group by ID,
VehNo,VehName,ValidTo,IMIE
,dr.DriID,DriName
SELECT * FROM #temp a INNER JOIN (SELECT Id,MAX([DateTime]) AS Dt FROM #temp
GROUP BY Id) b ON a.Id =b.Id AND a.[DateTime] = b.Dt
The suggested answer, in this post, works great for two columns.
I have about 50 different date columns, where I need to be able to report on the most recent interaction, regardless of table.
In this case, I am bringing the columns in to a view, since they are coming from different tables in two different databases...
CREATE VIEW vMyView
AS
SELECT
comp_name AS Customer
, Comp_UpdatedDate AS Last_Change
, CmLi_UpdatedDate AS Last_Communication
, Case_UpdatedDate AS Last_Case
, AdLi_UpdatedDate AS Address_Change
FROM Company
LEFT JOIN Comm_Link on Comp_CompanyId = CmLi_Comm_CompanyId
LEFT JOIN Cases ON Comp_CompanyId = Case_PrimaryCompanyId
LEFT JOIN Address_Link on Comp_CompanyId = AdLi_CompanyID
...
My question is, how I would easily account for the many possibilities of one column being greater than the others?
Using only the two first columns, as per the example above, works great. But considering that one row could have column 3 as the highest value, another row could have column 14 etc...
SELECT Customer, MAX(CASE WHEN (Last_Change IS NULL OR Last_Communication> Last_Change)
THEN Last_Communication ELSE Last_Change
END) AS MaxDate
FROM vMyView
GROUP BY Customer
So, how can I easily grab the highest value for each row in any of the 50(ish) columns?
I am using SQL Server 2008 R2, but I also need this to work in versions 2012 and 2014.
Any help would be greatly appreciated.
EDIT:
I just discovered that the second database is storing the dates in NUMERIC fields, rather than DATETIME. (Stupid! I know!)
So I get the error:
The type of column "ARCUS" conflicts with the type of other columns specified in the UNPIVOT list.
I tried to resolve this with a CAST to make it DATETIME, but that only resulted in more errors.
;WITH X AS
(
SELECT Customer
,Value [Date]
,ColumnName [Entity]
,BusinessEmail
,ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Value DESC) rn
FROM (
SELECT comp_name AS Customer
, Pers_EmailAddress AS BusinessEmail
, Comp_UpdatedDate AS Company
, CmLi_UpdatedDate AS Communication
, Case_UpdatedDate AS [Case]
, AdLi_UpdatedDate AS [Address]
, PLink_UpdatedDate AS Phone
, ELink_UpdatedDate AS Email
, Pers_UpdatedDate AS Person
, oppo_updateddate as Opportunity
, samdat.dbo.ARCUS.AUDTDATE AS ARCUS
FROM vCompanyPE
LEFT JOIN Comm_Link on Comp_CompanyId = CmLi_Comm_CompanyId
LEFT JOIN Cases ON Comp_CompanyId = Case_PrimaryCompanyId
LEFT JOIN Address_Link on Comp_CompanyId = AdLi_CompanyID
LEFT JOIN PhoneLink on Comp_CompanyId = PLink_RecordID
LEFT JOIN EmailLink on Comp_CompanyId = ELink_RecordID
LEFT JOIN vPersonPE on Comp_CompanyId = Pers_CompanyId
LEFT JOIN Opportunity on Comp_CompanyId = Oppo_PrimaryCompanyId
LEFT JOIN Orders on Oppo_OpportunityId = Orde_opportunityid
LEFT JOIN SAMDAT.DBO.ARCUS on IDCUST = Comp_IdCust
COLLATE Latin1_General_CI_AS
WHERE Comp_IdCust IS NOT NULL
AND Comp_deleted IS NULL
) t
UNPIVOT (Value FOR ColumnName IN
(
Company
,Communication
,[Case]
,[Address]
,Phone
,Email
,Person
,Opportunity
,ARCUS
)
)up
)
SELECT Customer
, BusinessEmail
,[Date]
,[Entity]
FROM X
WHERE rn = 1 AND [DATE] >= DATEADD(year,-2,GETDATE()) and BusinessEmail is not null
You could use CROSS APPLY to manually pivot your fields, then use MAX()
SELECT
vMyView.*,
greatest.val
FROM
vMyView
CROSS APPLY
(
SELECT
MAX(val) AS val
FROM
(
SELECT vMyView.field01 AS val
UNION ALL SELECT vMyView.field02 AS val
...
UNION ALL SELECT vMyView.field50 AS val
)
AS manual_pivot
)
AS greatest
The inner most query will pivot each field in to a new row, then the MAX() re-aggregate them back in to a single row. (Also skipping NULLs, so you don't need to explicitly cater for them.)
;WITH X AS
(
SELECT Customer
,Value [Date]
,ColumnName [CommunicationType]
,ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY Value DESC) rn
FROM (
SELECT comp_name AS Customer
, Comp_UpdatedDate AS Last_Change
, CmLi_UpdatedDate AS Last_Communication
, Case_UpdatedDate AS Last_Case
, AdLi_UpdatedDate AS Address_Change
FROM Company
LEFT JOIN Comm_Link on Comp_CompanyId = CmLi_Comm_CompanyId
LEFT JOIN Cases ON Comp_CompanyId = Case_PrimaryCompanyId
LEFT JOIN Address_Link on Comp_CompanyId = AdLi_CompanyID
) t
UNPIVOT (Value FOR ColumnName IN (Last_Change,Last_Communication,
Last_Case,Address_Change))up
)
SELECT Customer
,[Date]
,[CommunicationType]
FROM X
WHERE rn = 1
I have a table like so:
Id, Comment, LastUpdatedDate
I'm tyring to select the latest comment for that id. The table can have many comments on that id with different dates but I'm trying to get the latest date out of there. I've tried the following with no success:
SELECT tt.*
FROM tagtestresultcomment tt
INNER JOIN
(
SELECT tag_id, MAX(last_update) AS MaxDateTime
FROM tagtestresultcomment
GROUP BY tag_id
) groupedtt ON tt.tag_id = groupedtt.tag_id AND tt.last_update = groupedtt.MaxDateTime
order by tag_id
Does anyone have any ideas of how to achieve this?
Thanks!
It sounds like you want only the latest comment for each tag_id? In which case, here is one approach you can use from SQL 2005 and on:
;WITH CTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY tag_id ORDER BY last_update DESC) AS RowNo
FROM TagTestResultComment
)
SELECT * FROM CTE WHERE RowNo = 1
try this
Select * from tagtestresultcomment where last_update in
(select max(last_update) from tagtestresultcomment group by tag_id)
your query code is too redundant. first
tt.tag_id = groupedtt.tag_id AND tt.last_update = groupedtt.MaxDateTime
it's enough just
tt.tag_id = groupedtt.tag_id
and second, it's enough just
SELECT [desired field list extcept last_update and ],
tag_id,
MAX(last_update) AS MaxDateTime
FROM
tagtestresultcomment
group by
tag_id, [desired field list extcept last_update and tag_id]
at all to achieve your objective
I have tried something like this:
declare #tagtestresultcomment table
(
id int
, comment varchar(50)
,LastUpdatedDate datetime
)
--==== Populate table
insert into #tagtestresultcomment(id,comment,LastUpdatedDate)
select 1,'My name is Arthur','2011-06-09 00:00:00' union all
select 2,'My name is DW','2011-06-19 00:00:00' union all
select 2,'Arthur is my brother','2011-06-21 00:00:00' union all
select 1,'I have a sister named DW','2011-06-21 00:00:00' union all
select 3,'I am Muffy','2011-06-14 00:00:00' union all
select 3,'I like sports','2011-06-14 00:00:00'
-- SELECT stmt
select * from #tagtestresultcomment t
join
(
select id, MAX(lastupdateddate) as LastUpdatedDate from #tagtestresultcomment group by id
) m
on t.id = m.id
and t.LastUpdatedDate = m.LastUpdatedDate
The "MAX" group function wasn't working for me, so I used a sub-query. I had trouble wrapping my head around your single table example, so I'm using a common parent-child 1-to-many relationship with a blog and comment tables as an example.
SELECT
b.id,
b.content,
c.id,
c.blog_id,
c.content,
c.last_update
FROM blog b
INNER JOIN blog_comment c
ON b.id = c.blog_id AND c.id = (
SELECT TOP 1 id FROM blog_comment WHERE blog_id = b.id ORDER BY last_update DESC
)
The query takes a hit on my sub-query, as it will call that "SELECT TOP 1" query for each record in the blog table. I'd like to hear of a faster, more efficient example if possible.