ok this is a head wrecker and I will try to keep it brief.
I have two tables, Security and SecurityAudit
The Audit table keeps a copy of any changes to the Security table only if changes are made. The SecurityId is the Foriegn key. So the most recent record is always in the Security table and if there is a change then its written to the Audit table and the ValidToDate is set to the date the record was valid up to
[Security](
[SecurityID] [bigint] IDENTITY(10000,1) NOT NULL,
[Security] [nvarchar](255) NOT NULL,
[ISIN] [nvarchar](20) NOT NULL,
[CountryOfIncID] [bigint] NOT NULL,
[SecurityTypeID] [bigint] NOT NULL,
[SubTypeID] [bigint] NOT NULL,
[ISQ] [bigint] NOT NULL,
[MemberStateID] [bigint] NULL,
[ManualOverride] [bit] NULL,
here is the Audit table
[SecurityAudit](
[SecurityAuditID] [bigint] IDENTITY(10000,1) NOT NULL,
[SecurityID] [bigint] NOT NULL,
[Security] [nvarchar](255) NOT NULL,
[CountryOfIncID] [bigint] NOT NULL,
[SubTypeID] [bigint] NOT NULL,
[ISQ] [bigint] NOT NULL,
[MemberStateID] [bigint] NULL,
[ValidToDateID] [datetime] Not NULL
So my problem is I now want to get all the securities that where in play at a particular point in time. This means get all the securities that have never had a change from the security table and then the relevant security from the Audit table for that point in time.
I thought I would do this using a CTE, and Union and a Rank but I,ve hit a wall. Its looking like this so far…
With
cteAllSecurities (RowNum,SecurityID, Security, ISQ, CountryOfIncorporationID, ValidToDate)
AS
(
SELECT RowNum=row_number() OVER (Partition By Security order by ValidToDate desc),
sa.SecurityID, sa.Security, sa.ISQ, sa.CountryOfIncorporationID, CONVERT(varchar(30), sa.ValidToDate,106)
FROM
SecurityAudit sa
UNION
SELECT 0 as RowNum,
s.SecurityID, s.Security, s.ISQ, s.CountryOfIncorporationID, CONVERT(varchar(30), GetUtcDate(),106) as ValidToDate
FROM
Security s
)
SELECT RowNum, SecurityID, Security, ISQ, CountryOfIncorporationID, ValidToDate
FROM cteAllSecurities
order by securityid
Where row_number() = 1
so I union the Securites table which has the last with the Audit and give them a row number. I was then hoping to get all the securities that have a row number of 0 and no child records… ie a child count of 0 in the audit table and the Audit Records that are less than the date I’m looking for and take the top one.
So I,ve got so far. Am I on the right tracks, over cooking it, or just plan mad. Any help would be greatly appreciated.
Regards M
I think you should be able to get the results you’re looking for with a query such as this:
You’ll obviously want to replace
@SearchDatewith the value you’re looking for.This query will union the “current” security table, setting the ValidToDate to the maximum
DATETIMEvalue that SQL Server accepts, and unions it with the Audit Table. Then, using a subquery, we get the “closest” (minimum) ValidToDate that’s larger than the date we’re looking at.