Home > other >  SQL query to identify active records by filtering out rest of the records
SQL query to identify active records by filtering out rest of the records

Time:11-01

There's one DB table 'SiteTransactions' (in Sql Server) which currently has the records in following sample format

Id TransactionType SiteGroup SiteName TransactionTime
1 Create SG1 TestSite1 2021-08-27 19:22:26.4318370
2 Delete SG1 TestSite1 2021-08-28 09:22:26.4318370
3 Create SG2 TestSite2 2021-08-28 10:12:26.4318370
4 Create SG1 TestSite3 2021-08-29 19:22:00.4318370
5 Delete SG2 TestSite2 2021-08-30 08:04:26.4318370
6 Create SG2 TestSite2 2021-08-31 20:18:26.4318370
7 Delete SG2 TestSite2 2021-08-31 20:20:26.4318370

This table stores all of the SiteName transaction details. Both Create and Delete transactions are stored in this same table. The problem here is that there is no dedicated identifier column which can tell whether a given SiteGroup-SiteName combination is currently active (i.e. not yet been deleted)

SiteName is always unique and no 2 active SiteNames can have same name UNLESS a given SiteName has been previously deleted. 'TestSite2' in above table example.

Requirement

The requirement as mentioned above is to get a list of active only SiteGroup-SiteName combination which have not been deleted yet.

Only way to do so is to check if any SiteGroup-SiteName combination has a Delete transaction type value or not and compare the TransactionTime.

The correct output for above sample table should be as follows since only TestSite3 after once created has not been deleted (hence it's considered to be active):

Id TransactionType SiteGroup SiteName
4 Create SG1 TestSite3

What I Tried

Right now I've built following query by comapring TransactionTime timestamps:

SELECT DISTINCT(A.SiteName), A.SiteGroup, A.TransactionType, A.TransactionTime
FROM SiteTransactions A, SiteTransactions B
WHERE A.SiteName= B.SiteNameAND A.SiteGroup = B.SiteGroup 
AND A.TransactionType = 'Create'
AND A.TransactionTime> B.TransactionTime
ORDER BY A.TransactionTime DESC

But the problem with my query is that it also returns TestSite2 records (which has been deleted twice) due to the TransactionTime comparison check I have in place

What would be the tweak I need to make to get the required output?

CodePudding user response:

You can use a conditional windowed count for this

SELECT
  Id,
  TransactionType,
  SiteGroup,
  SiteName
FROM (
    SLEECT *,
      cnt = COUNT(CASE WHEN TransactionType = 'Delete' THEN 1 END)
              OVER (PARTITION BY SiteGroup, SiteName
                   ORDER BY TransactionTime ROWS UNBOUNDED PRECEDING)
    FROM YourTable t
) t
WHERE cnt = 0;

CodePudding user response:

You can use the Row_Number ranking function to determine the type of the last transaction in each group.

Select ID, TransactionType, SiteGroup, SiteName
From 
(Select ID, TransactionType, SiteGroup, SiteName,
Row_Number() Over (Partition by SiteGroup, SiteName Order by TransactionTime Desc) As Num
From SiteTransactions) As t
Where Num=1 And TransactionType='Create'
  • Related