Select the most recent row where 2 columns contain the same value - sql

I have a table of street codes and county codes. I need to only select the most recent row (ordered by created date) of any rows where these 2 columns are the same.
Ex.
Here only the last row should be selected, since it has the newest created date, where the Kommunekode and Vejkode are the same.
How can I filter my select statement to allow this logic? I tried using the distinct keyword, but that does not take the Created date into account.
My current code for the view:
SELECT
Infohub_RowId,
Infohub_CreatedDate,
Id,
Sekvensnummer,
Tidspunkt,
Operation,
Kommunekode,
Vejkode,
Oprettet,
Aendret,
Navn,
Vejnavn,
Navngivenvej_id,
Aendret AS Infohub_ValidityDate
FROM (
SELECT
Infohub_RowId,
Infohub_CreatedDate,
Sekvensnummer,
Tidspunkt,
Operation,
Id,
Kommunekode,
Vejkode,
Oprettet,
Aendret,
Navn,
Vejnavn,
Navngivenvej_id,
ROW_NUMBER() OVER(PARTITION BY Id ORDER BY Aendret DESC) AS RowNum
FROM
Dawa.tDelta_Vejstykke) AS x
WHERE x.RowNum = 1
The view should "clean up" the data, by selecting the newest duplicate records.

use Infohub_CreatedDate in order by and Kommunekode,Vejkode these two column in partition by
SELECT
Infohub_RowId,
Infohub_CreatedDate,
Id,
Sekvensnummer,
Tidspunkt,
Operation,
Kommunekode,
Vejkode,
Oprettet,
Aendret,
Navn,
Vejnavn,
Navngivenvej_id,
Aendret AS Infohub_ValidityDate
FROM (
SELECT
Infohub_RowId,
Infohub_CreatedDate,
Sekvensnummer,
Tidspunkt,
Operation,
Id,
Kommunekode,
Vejkode,
Oprettet,
Aendret,
Navn,
Vejnavn,
Navngivenvej_id,
ROW_NUMBER() OVER(PARTITION BY Kommunekode,
Vejkode ORDER BY Infohub_CreatedDate DESC) AS RowNum
FROM
Dawa.tDelta_Vejstykke) AS x
WHERE x.RowNum = 1

You want row_number() but Kommunekode, Vejkode should be in partition clause :
SELECT t.*
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY Kommunekode, Vejkode ORDER BY Infohub_CreatedDate DESC) AS Seq
FROM Dawa.tDelta_Vejstykke t
) t
WHERE Seq = 1;

Related

Get last and first record using rank()

I need to get first and last record (ordered by Date column) from table for certain SSID. It is not a problem if there is more records with same max or min date. All I need is union all.
I am getting last record having max(date) with:
with c as (
select *, rnk = rank() over (partition by Date order by Date ASC)
from table
where SSID = '00921834800'
)
select top 1 Date, City, Title
from c
order by Date desc
How to I get first record (min(Date)) as well (same thing only with order by Date asc) with single select and without using ranking again?
I'm using MSSQL 2017.
; with c as (
select *,
rnk = rank() over (partition by Date order by Date ASC),
rnk2 = rank() over (partition by Date order by Date desc)
from table
where SSID= '00921834800'
)
select Date,
City,
Title
from c
where rnk = 1 or rnk2 = 1
order by Date desc
I would use the following query:
select * from (select top 1 with ties * from t where ssid = '00921834800' order by date) as a
union all
select * from (select top 1 with ties * from t where ssid = '00921834800' order by date desc) as b
One other solution is :
with
c as
(
select *,
rank() over (partition by Date order by Date ASC) AS RNK,
count() OVER (partition by Date) AS CNT
from table
where SSID= '00921834800')
select Date, City, Title
from c
WHERE RNK = 1
OR CNT = RNK
order by Date desc

Select an id from a group sql which returns duplicate records?

I have to select CompanyId column only from the following SQL;
select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA'
In the SQL, I try to figure out duplicate records, and from another table i want to delete some records based on the CompanyId from above query.
that is;
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA')
How can I modify above query?
Assuming you don't care which duplicate gets retained or deleted, you may try using a deletable CTE here:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [GradeName] ORDER BY [TankNumber]) rn
FROM [Data_DB].[dbo].[Company]
WHERE CompanyCode = 'ASAAA'
)
DELETE
FROM cte
WHERE rn > 1;
This answer arbitrarily retains the "first" duplicate, with first being defined as the record with the earliest row number.
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId from (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Datat_DB].[dbo].[Company] where CompanyCode='ASAAA') a where rn > 1 ;

How to get single closest value for each column type in DB2

I have this query:
SELECT * FROM TABLE1 WHERE KEY_COLUMN='NJCRF' AND TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3') AND DATE_EFFECTIVE_COLUMN<='2016-09-17'
I get about 12 record(rows) as result.
How to get result closest to DATE_EFFECTIVE_COLUMN for each TYPE_COLUMN? In this case, how to get three records, for each type, that are closest to effective date?
UPDATE: I could use TOP if I had to go over only single type, but I have three at this moment and for each of them I need to get closest time result.
Hope I made it clear, let me know if you need more info.
If I understand correctly, you can use ROW_NUMBER():
SELECT t.*
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY TYPE_COLUMN ORDER BY DATE_EFFECTIVE_COLUMN DESC) as seqnum
FROM TABLE1 t
WHERE KEY_COLUMN = 'NJCRF' AND
TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3') AND
DATE_EFFECTIVE_COLUMN <= '2016-09-17'
) t
WHERE seqnum = 1;
If you want three records per type, just use seqnum <= 3.
I like ROW_NUMBER() for this. You want to partition by TYPE, which will start the row count over for each type, then order by DATE_EFFECTIVE desc, and take only the highest date (the first row):
SELECT *
FROM (
SELECT *,
ROW_NUMBER() over (PARTITION BY TYPE_COLUMN ORDER BY DATE_EFFECTIVE_COLUMN desc) RN
FROM TABLE1
WHERE KEY_COLUMN = 'NJCRF'
AND TYPE_COLUMN IN ('SCORE1', 'SCORE2', 'SCORE3')
AND DATE_EFFECTIVE_COLUMN <= '2016-09-17'
) A
WHERE RN = 1

SQL oracle Select condition in group

Let's suppose I have a table with 3 columns:
ID | GroupId | DateCreatedOn |
I want to select the datas grouped by GroupId so:
select GroupId from tableName group by GroupId;
But what if I want to execute another select on each group? let's suppose now that I want the last created row (DateCreatedOn) of each group?
Also, I would like to retrieve ALL the columns and not only the GroupId.
Im kind of lost because I only have GroupId available.
Please provide some explanation and not only the correct query.
You can use ROW_NUMBER for this:
SELECT ID, GroupId, DateCreatedOn
FROM (
SELECT ID, GroupId, DateCreatedOn,
ROW_NUMBER() OVER (PARTITION BY GroupId
ORDER BY DateCreatedOn DESC) AS rn
FROM mytable) t
WHERE t.rn = 1
rn field is equal to 1 for the record having the most recent DateCreatedOn value within each GroupId partition.
You can get the values with the maximum of another column using KEEP ( DENSE_RANK [FIRST|LAST] ORDER BY ... ) in the aggregation:
SELECT GroupID,
MAX( ID ) KEEP ( DENSE_RANK LAST ORDER BY DateCreatedOn ) AS id
MAX( DateCreatedOn ) AS DateCreatedOn
FROM table_name
GROUP BY GroupId
You can also do it using ROW_NUMBER():
SELECT ID,
GroupID,
DateCreatedOn
FROM (
SELECT t.*,
ROW_NUMBER() OVER ( PARTITION BY GroupID
ORDER BY DateCreatedOn DESC, ID DESC ) AS RN
FROM table_name t
)
WHERE RN = 1
(ID DESC is added to the ORDER BY to get the maximum ID for the latest DateCreatedOn to give the same result as the first query; if you don't have a deterministic order then you are likely to get whichever row the database produces first and the result can be non-deterministic)

How to select distinct records based on condition

I have table of duplicate records like
Now I want only one record from duplicate records which has latest created date as How can I do it ?
use row_number():
select EnquiryId, Name, . . .
from (select t.*,
row_number() over (partition by enquiryID order by CreatedDate desc) as seqnum
from table t
) t
where seqnum = 1;
Use ROW_NUMBER function to tag the duplicate records ordered by CreatedDate, like this:
;with CTE AS (
select *, row_NUMBER() over(
partition by EnquiryID -- add columns on which you want to identify duplicates
ORDER BY CreatedDate DESC) as rn
FROM TABLE
)
select * from CTE
where rn = 1